乐于分享
好东西不私藏

某招聘软件算法分析

某招聘软件算法分析

某招聘软件算法分析

本文章中所有内容仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关;本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文涉及的技术而导致的任何意外,作者均不负责;

1. 概述

包名:com.hpbr.bosszhipin版本:13.141

  • • 我们的目标是搜索,需要提前登录;算法整体难度算中等,样本链接我会放在结尾处;
  • • 总体涉及md5、rc4、base64、LZ压缩这几个东西,需要提前了解一下这些算法;

2. 抓包&定位

  • • 首先进行抓包,确定目标参数;搜索之后找/api/batch/batchRunV2这个接口,主要目标是sp、sig、还有返回值看起来是加密的,接下来就逐个分析;
  • • 估计它们不一定在同一个位置,先看看吧,定位采用什么方式都可以,能定位到的方法都是好方法;
  • • 直接搜索定位看看,有没有比较显眼的位置;
  • • 最后一个显然是要合理一点的,进去看看;
  • • sig和sp都在,有可能是这里,继续跟一下就可以发下它们的native函数,我不放图了,把对应的结果写下来吧;
1
2

sig:private static native byte[] nativeSignature(byte[] bArr, String str);sp: private static native String nativeEncodeRequest(byte[] bArr, String str);

  • • 对应的so应该是libyzwg.so;
1

private static final String LIB_NAME = "yzwg";

  • • 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

function showByteArray(byteArray, name) {    if (byteArray == null) return;    var result = Java.use('java.lang.String').$new(Java.array('byte', byteArray)).toString();    console.log(name + ": " + result);}function hook_sig() {    Java.perform(function () {        let com_twl_signer_YZWG = Java.use("com.twl.signer.YZWG");        com_twl_signer_YZWG["nativeSignature"].implementation = function (bArr, str) {            console.log(`[->] chook_sig ->str= ${str}`);            showByteArray(bArr, "hook_sig bArr");            var retval = this["nativeSignature"](bArr, str);            showByteArray(retval, "hook_sig 返回值")            return retval;        };    });}function hook_sp() {    Java.perform(function () {        let com_twl_signer_YZWG = Java.use("com.twl.signer.YZWG");        com_twl_signer_YZWG["nativeEncodeRequest"].implementation = function (bArr, str) {            console.log(`[->] hook_sp ->str= ${str}`);            showByteArray(bArr, "hook_sp bArr");            var retval = this["nativeEncodeRequest"](bArr, str);            console.log(`[<-] hook_sp retval= ${retval}`);            return retval;        };    });}hook_sig();hook_sp();

  • • hook结果如下,我只展示和目标接口对应的部分,因为接口触发可能比较多;
1
2
3
4
5
6

[->] hook_sp ->str= nullhook_sp bArr: batch_method_feed=%5B%22method%3Dzpgeek.app.geek.search.cardlist%26encryptExpectId%3D4617621d9b2479b31nZ82tu0FFRSwA%257E%257E%26expectId%3D1261694622%26filterParams%3D%257B%2522cityCode%2522%253A%2522101010100%2522%252C%2522chattedJob%2522%253A0%252C%2522switchCity%2522%253A0%252C%2522labelFilter%2522%253A%257B%2522tags%2522%253A%255B%257B%2522code%2522%253A%2522-1%2522%252C%2522tag%2522%253A%2522%25E4%25B8%258D%25E9%2599%2590%2522%257D%255D%252C%2522type%2522%253A2%257D%257D%26isFromJd%3D0%26isSupplySearch%3Dfalse%26jids%3D%26maskComType%3D0%26naturalLanguageParam%3D%26noCorrect%3D0%26page%3D1%26prefix%3Dh%26pushId%3D%26pushType%3D%26query%3Dpython%26queryId%3D%26queryTitle%3D%25E6%2590%259C%25E7%25B4%25A2%25E5%258F%2591%25E7%258E%25B0%26searchType%3D3%26sort%3D-1%26source%3D1%26sugAbKey%3DM69-GroupA%26sugSessionId%3D1VpO529c1Ho%26userIntent%3D%22%2C+%22method%3Dzpgeek.app.search.listad.query%26encryptExpectId%3D4617621d9b2479b31nZ82tu0FFRSwA%257E%257E%26filterParams%3D%257B%2522cityCode%2522%253A%2522101010100%2522%252C%2522chattedJob%2522%253A0%252C%2522switchCity%2522%253A0%252C%2522labelFilter%2522%253A%257B%2522tags%2522%253A%255B%257B%2522code%2522%253A%2522-1%2522%252C%2522tag%2522%253A%2522%25E4%25B8%258D%25E9%2599%2590%2522%257D%255D%252C%2522type%2522%253A2%257D%257D%26page%3D1%26query%3Dpython%26sort%3D-1%22%5D&client_info=%7B%22version%22%3A%2212%22%2C%22os%22%3A%22Android%22%2C%22start_time%22%3A%221771739823352%22%2C%22resume_time%22%3A%221771739823352%22%2C%22channel%22%3A%2228%22%2C%22model%22%3A%22google%7C%7CPixel+6%22%2C%22dzt%22%3A0%2C%22loc_per%22%3A0%2C%22uniqid%22%3A%223880525a-bdb9-41fb-b8bc-b38d1addd229%22%2C%22oaid%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22oaid_honor%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22did%22%3A%22DUYlEEPTkR_1kujGVuif0etPK8a41fRRHAa0RFVZbEVFUFRrUl8xa3VqR1Z1aWYwZXRQSzhhNDFmUlJIQWEwc2h1%22%2C%22tinker_id%22%3A%22Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09%22%2C%22is_bg_req%22%3A0%2C%22network%22%3A%22wifi%22%2C%22operator%22%3A%22UNKNOWN%22%2C%22abi%22%3A1%7D&curidentity=0&req_time=1771741084302&uniqid=3880525a-bdb9-41fb-b8bc-b38d1addd229&v=13.141[<-] hook_sp retval= zwp_NCTRJTSwi3DeUsbkHIGNvU2MDIbyc_aI7pY7DTCAI7RtvzRtOHFgg3UWfOUMTO-UsQF6fAyw-rVGYJBSi6J1KX-FB70JplcewoyOd-dpWuhTl7gbHswG3N8n30lJuDL2_nFt0ONQG0-n42W9F8pD_iIs5mq-AKEi0RN8II4pDgJnH9pbEYKs0O0saFB8dqc6YRZJEJ0Iie7ZpgbwE2wwiQ_MU0Ko9XgrB6fBA_1dNFmp8z_--LNoBZBVyly3CrZasgjpOc5CqKwRiUrLgeb7BHBrymEAHlZDe_BQ8P1lQpGLHh-drdx6NqVHe86G_duGsfA0DoPuKyRaOSH75-PTb9Yub10pIs6LahfPutgSjC2BC09B1CSPjQPp8V2iQL20_x_unCd8sM5VGCTCr3fp9uIE18Rr7h2AMpAfS2xulAGlUjQhDFlyLkNvAWwbXzxVw8ax66GA9lv2bMdJVgs1HyvLF0rTX_ogaeu1FtgtPcGwzQcZ6ePWCAz2ciJdGH_u06080i88ensJkyDQDsnuuq-II60b4YmmKcHvUajXdbx0cDa1ycsUdnY-MDgKcLCbmgrDR5yX2dwcK7j8CzlC0SIQciE6Uc0SmPvpotX-eMKVGNlvblAg-XhXapAGzh7FwgfkDhGobrDNJ7lrCGu7IsKm-LAmuBPJUwV5QX0rWlkMM2xbo4UF1CskcpwwdPGEmg5eNxblPz3twdT_J6UqTMf63ORXTdROYuRT5D12saAMLm6gcjeaSk06KWura_DeVO_10mNKdk7yPf1rtwWuiG2WVwGKZLm7Oab_6NREKqkHMiXBc0d0r7hIWoC0Hi1aAB-h1boc91JBaZYLMN1tq3QWhDr_E0MrsjIHAO_jLhC56IcCQIYg44lmg3nvwrcbpqr6LzM6484_mTRummQWwOr5QFbqFtucP_elAVo5oNqbL_UrpbNjpcd_IdRn1wN4ak9HgBKWyXZvz1t-DNAGzA-EY-P_oP5etPcmoeO5C4Mt8eU-w_HO4aJljV0CQU_KnxyKB9Jfo_7o3E61W38LSlX6vxfaMQtmVDNjzERTXoMK73Q0KnWdd9RQEwn2bL1f9ruh2ngZvUG4PRaFp5w9dMq2-u-VU-0yjIJN81kbWcvHDoEVtT5MdubBYy3uNhetDoKY1NiiOFK7RWsDSB_K_a1ULaxaW2mun3Q4Qt8bkz4QyNwTF146dPhJxzrDQpx0ExNMvmBQRi7I9H-DY-ZJBLSIBn8tOSeb-2nWWN2cP_dl2Li9vk9jk5megfnb8LplyyA6WfD2MXhjYkVvUTgJ403oy0bYGYE7An3wOGOkmmK2Ip84EYPnKfcuMsihH-QUfUPzDGX-QWFzdj9X8GoEwevatOO0itUY7aMfLcW9icX0pziGDXIGv1rCo5xZSteXjc7besqHQpAxSkVKeqa2KQt33XmCjeJgE-Oh5X_ENG4bH7q5I9HLaLPBox7hSSUbq9NHay29dAZCPwujW9JnLsrm8BdACCpjO62Zl7IkKgoQ3ZgmQIkk1PYqUWSoOYMXQHCxL9SYRE4QcMs3UcUdw6_FWXokQalqSgqEwQfI0ZV4VqUkgf7qek59tggzKAA7N1eInXA_HXqX0wVNVznyrL0hkKXx50fmKxV7WrwitKRg2qXLr1I22-mhekVR8QUh-BiAog0Lqhf2mej1esVdBiqRq2CPmMJeN8I~[->] chook_sig ->str= nullhook_sig bArr: /api/batch/batchRunV2batch_method_feed=%5B%22method%3Dzpgeek.app.geek.search.cardlist%26encryptExpectId%3D4617621d9b2479b31nZ82tu0FFRSwA%257E%257E%26expectId%3D1261694622%26filterParams%3D%257B%2522cityCode%2522%253A%2522101010100%2522%252C%2522chattedJob%2522%253A0%252C%2522switchCity%2522%253A0%252C%2522labelFilter%2522%253A%257B%2522tags%2522%253A%255B%257B%2522code%2522%253A%2522-1%2522%252C%2522tag%2522%253A%2522%25E4%25B8%258D%25E9%2599%2590%2522%257D%255D%252C%2522type%2522%253A2%257D%257D%26isFromJd%3D0%26isSupplySearch%3Dfalse%26jids%3D%26maskComType%3D0%26naturalLanguageParam%3D%26noCorrect%3D0%26page%3D1%26prefix%3Dh%26pushId%3D%26pushType%3D%26query%3Dpython%26queryId%3D%26queryTitle%3D%25E6%2590%259C%25E7%25B4%25A2%25E5%258F%2591%25E7%258E%25B0%26searchType%3D3%26sort%3D-1%26source%3D1%26sugAbKey%3DM69-GroupA%26sugSessionId%3D1VpO529c1Ho%26userIntent%3D%22%2C+%22method%3Dzpgeek.app.search.listad.query%26encryptExpectId%3D4617621d9b2479b31nZ82tu0FFRSwA%257E%257E%26filterParams%3D%257B%2522cityCode%2522%253A%2522101010100%2522%252C%2522chattedJob%2522%253A0%252C%2522switchCity%2522%253A0%252C%2522labelFilter%2522%253A%257B%2522tags%2522%253A%255B%257B%2522code%2522%253A%2522-1%2522%252C%2522tag%2522%253A%2522%25E4%25B8%258D%25E9%2599%2590%2522%257D%255D%252C%2522type%2522%253A2%257D%257D%26page%3D1%26query%3Dpython%26sort%3D-1%22%5D&client_info=%7B%22version%22%3A%2212%22%2C%22os%22%3A%22Android%22%2C%22start_time%22%3A%221771739823352%22%2C%22resume_time%22%3A%221771739823352%22%2C%22channel%22%3A%2228%22%2C%22model%22%3A%22google%7C%7CPixel+6%22%2C%22dzt%22%3A0%2C%22loc_per%22%3A0%2C%22uniqid%22%3A%223880525a-bdb9-41fb-b8bc-b38d1addd229%22%2C%22oaid%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22oaid_honor%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22did%22%3A%22DUYlEEPTkR_1kujGVuif0etPK8a41fRRHAa0RFVZbEVFUFRrUl8xa3VqR1Z1aWYwZXRQSzhhNDFmUlJIQWEwc2h1%22%2C%22tinker_id%22%3A%22Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09%22%2C%22is_bg_req%22%3A0%2C%22network%22%3A%22wifi%22%2C%22operator%22%3A%22UNKNOWN%22%2C%22abi%22%3A1%7D&curidentity=0&req_time=1771741084302&uniqid=3880525a-bdb9-41fb-b8bc-b38d1addd229&v=13.141hook_sig 返回值: V3.0f28a35d5baff6f9c44f199a292bece55

  • • 参数非常长,而且有url编码,解码一下,这里需要多次解码;
1
2
3
4
5
6
7

[->] hook_sp ->str= nullhook_sp bArr: batch_method_feed=["method=zpgeek.app.geek.search.cardlist&encryptExpectId=4617621d9b2479b31nZ82tu0FFRSwA~~&expectId=1261694622&filterParams={"cityCode":"101010100","chattedJob":0,"switchCity":0,"labelFilter":{"tags":[{"code":"-1","tag":"不限"}],"type":2}}&isFromJd=0&isSupplySearch=false&jids=&maskComType=0&naturalLanguageParam=&noCorrect=0&page=1&prefix=h&pushId=&pushType=&query=python&queryId=&queryTitle=搜索发现&searchType=3&sort=-1&source=1&sugAbKey=M69-GroupA&sugSessionId=1VpO529c1Ho&userIntent=", "method=zpgeek.app.search.listad.query&encryptExpectId=4617621d9b2479b31nZ82tu0FFRSwA~~&filterParams={"cityCode":"101010100","chattedJob":0,"switchCity":0,"labelFilter":{"tags":[{"code":"-1","tag":"不限"}],"type":2}}&page=1&query=python&sort=-1"]&client_info={"version":"12","os":"Android","start_time":"1771739823352","resume_time":"1771739823352","channel":"28","model":"google||Pixel 6","dzt":0,"loc_per":0,"uniqid":"3880525a-bdb9-41fb-b8bc-b38d1addd229","oaid":"00000000-0000-0000-0000-000000000000","oaid_honor":"00000000-0000-0000-0000-000000000000","did":"DUYlEEPTkR_1kujGVuif0etPK8a41fRRHAa0RFVZbEVFUFRrUl8xa3VqR1Z1aWYwZXRQSzhhNDFmUlJIQWEwc2h1","tinker_id":"Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09","is_bg_req":0,"network":"wifi","operator":"UNKNOWN","abi":1}&curidentity=0&req_time=1771741084302&uniqid=3880525a-bdb9-41fb-b8bc-b38d1addd229&v=13.141[<-] hook_sp retval= zwp_NCTRJTSwi3DeUsbkHIGNvU2MDIbyc_aI7pY7DTCAI7RtvzRtOHFgg3UWfOUMTO-UsQF6fAyw-rVGYJBSi6J1KX-FB70JplcewoyOd-dpWuhTl7gbHswG3N8n30lJuDL2_nFt0ONQG0-n42W9F8pD_iIs5mq-AKEi0RN8II4pDgJnH9pbEYKs0O0saFB8dqc6YRZJEJ0Iie7ZpgbwE2wwiQ_MU0Ko9XgrB6fBA_1dNFmp8z_--LNoBZBVyly3CrZasgjpOc5CqKwRiUrLgeb7BHBrymEAHlZDe_BQ8P1lQpGLHh-drdx6NqVHe86G_duGsfA0DoPuKyRaOSH75-PTb9Yub10pIs6LahfPutgSjC2BC09B1CSPjQPp8V2iQL20_x_unCd8sM5VGCTCr3fp9uIE18Rr7h2AMpAfS2xulAGlUjQhDFlyLkNvAWwbXzxVw8ax66GA9lv2bMdJVgs1HyvLF0rTX_ogaeu1FtgtPcGwzQcZ6ePWCAz2ciJdGH_u06080i88ensJkyDQDsnuuq-II60b4YmmKcHvUajXdbx0cDa1ycsUdnY-MDgKcLCbmgrDR5yX2dwcK7j8CzlC0SIQciE6Uc0SmPvpotX-eMKVGNlvblAg-XhXapAGzh7FwgfkDhGobrDNJ7lrCGu7IsKm-LAmuBPJUwV5QX0rWlkMM2xbo4UF1CskcpwwdPGEmg5eNxblPz3twdT_J6UqTMf63ORXTdROYuRT5D12saAMLm6gcjeaSk06KWura_DeVO_10mNKdk7yPf1rtwWuiG2WVwGKZLm7Oab_6NREKqkHMiXBc0d0r7hIWoC0Hi1aAB-h1boc91JBaZYLMN1tq3QWhDr_E0MrsjIHAO_jLhC56IcCQIYg44lmg3nvwrcbpqr6LzM6484_mTRummQWwOr5QFbqFtucP_elAVo5oNqbL_UrpbNjpcd_IdRn1wN4ak9HgBKWyXZvz1t-DNAGzA-EY-P_oP5etPcmoeO5C4Mt8eU-w_HO4aJljV0CQU_KnxyKB9Jfo_7o3E61W38LSlX6vxfaMQtmVDNjzERTXoMK73Q0KnWdd9RQEwn2bL1f9ruh2ngZvUG4PRaFp5w9dMq2-u-VU-0yjIJN81kbWcvHDoEVtT5MdubBYy3uNhetDoKY1NiiOFK7RWsDSB_K_a1ULaxaW2mun3Q4Qt8bkz4QyNwTF146dPhJxzrDQpx0ExNMvmBQRi7I9H-DY-ZJBLSIBn8tOSeb-2nWWN2cP_dl2Li9vk9jk5megfnb8LplyyA6WfD2MXhjYkVvUTgJ403oy0bYGYE7An3wOGOkmmK2Ip84EYPnKfcuMsihH-QUfUPzDGX-QWFzdj9X8GoEwevatOO0itUY7aMfLcW9icX0pziGDXIGv1rCo5xZSteXjc7besqHQpAxSkVKeqa2KQt33XmCjeJgE-Oh5X_ENG4bH7q5I9HLaLPBox7hSSUbq9NHay29dAZCPwujW9JnLsrm8BdACCpjO62Zl7IkKgoQ3ZgmQIkk1PYqUWSoOYMXQHCxL9SYRE4QcMs3UcUdw6_FWXokQalqSgqEwQfI0ZV4VqUkgf7qek59tggzKAA7N1eInXA_HXqX0wVNVznyrL0hkKXx50fmKxV7WrwitKRg2qXLr1I22-mhekVR8QUh-BiAog0Lqhf2mej1esVdBiqRq2CPmMJeN8I~[->] hook_sig ->str= nullhook_sig bArr: /api/batch/batchRunV2batch_method_feed=["method=zpgeek.app.geek.search.cardlist&encryptExpectId=4617621d9b2479b31nZ82tu0FFRSwA~~&expectId=1261694622&filterParams={"cityCode":"101010100","chattedJob":0,"switchCity":0,"labelFilter":{"tags":[{"code":"-1","tag":"不限"}],"type":2}}&isFromJd=0&isSupplySearch=false&jids=&maskComType=0&naturalLanguageParam=&noCorrect=0&page=1&prefix=h&pushId=&pushType=&query=python&queryId=&queryTitle=搜索发现&searchType=3&sort=-1&source=1&sugAbKey=M69-GroupA&sugSessionId=1VpO529c1Ho&userIntent=", "method=zpgeek.app.search.listad.query&encryptExpectId=4617621d9b2479b31nZ82tu0FFRSwA~~&filterParams={"cityCode":"101010100","chattedJob":0,"switchCity":0,"labelFilter":{"tags":[{"code":"-1","tag":"不限"}],"type":2}}&page=1&query=python&sort=-1"]&client_info={"version":"12","os":"Android","start_time":"1771739823352","resume_time":"1771739823352","channel":"28","model":"google||Pixel 6","dzt":0,"loc_per":0,"uniqid":"3880525a-bdb9-41fb-b8bc-b38d1addd229","oaid":"00000000-0000-0000-0000-000000000000","oaid_honor":"00000000-0000-0000-0000-000000000000","did":"DUYlEEPTkR_1kujGVuif0etPK8a41fRRHAa0RFVZbEVFUFRrUl8xa3VqR1Z1aWYwZXRQSzhhNDFmUlJIQWEwc2h1","tinker_id":"Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09","is_bg_req":0,"network":"wifi","operator":"UNKNOWN","abi":1}&curidentity=0&req_time=1771741084302&uniqid=3880525a-bdb9-41fb-b8bc-b38d1addd229&v=13.141hook_sig 返回值: V3.0f28a35d5baff6f9c44f199a292bece55

  • • 简单对比可以发现,两个方法的bArr其实是一样的,只是sig的多了一个当前接口拼在最前面,而且两个字符串都是null,所以这两个参数描述的东西是一样的,只是形式不一样;
  • • 后续unidbg主动调用的时候记得传原始的参数,这里只是为了方便看而已,相对来说,响应的解密应当也是这个位置才对;
  • • 我们顺便也把它的函数找出来,我是比较偏向于它们都在同一个so的,而且附近也有类似的函数;
  • • 我猜测是选中的这两个函数之一,我们都hook上试试,看看是不是他们之一;
1
2
3
4
5
6
7

[->] nativeDecodeContent is called!->bArr= -49,10,127,52,36,-47,37,52,-80,-117,112,-34,-61,-15,-28···省略部分数据···,123,-113,-3,-62    ->str= null    ->i11= 0    ->i12= 1    ->i13= 2nativeDecodeContent retval: {"code":0,"message":"Success","zpData":{"zpgeek.app.geek.search.cardlist":{"code":0,"message":"Success","zpData":{"askAiEntrance":false,"cardList":[{"brandCardStyle":0,"hasMore":true,"jobCardStyle":0,"positionSearchCardList":[{"afterNameIcons":[{"height":48,"url":"https://img.bosszhipin.com/beijin/icon/20250107/b0d69dde1b861aef40e116820c982b289df0490b3b48e06fecc269e8d551a6fe1adc516614a77077.png","width":48}],"areaBusinessName":"望京","areaDistrict":"朝阳区","bossOnline":{"detailOnlin····省略部分数据····"zpData":{"listAds":[]}}}}

  • • 可以发现,确实走了,而且是参数比较多的那一个函数,到这里三个函数我们都定位好了;后续开始分析具体的算法,先把unidbg跑通;这里在unidbg调用的时候注意这几个int参数,有些时候第三个并不是2,自己注意就好了;
  • • 对了,bArr这个参数就是返回值,可以去cyberchef测试一下,是一样的;

3. 模拟执行

  • • 首先搭一个基本的框架;
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

package com.Samples.boss;import com.github.unidbg.AndroidEmulator;import com.github.unidbg.Emulator;import com.github.unidbg.Module;import com.github.unidbg.arm.backend.Unicorn2Factory;import com.github.unidbg.arm.context.RegisterContext;import com.github.unidbg.debugger.BreakPointCallback;import com.github.unidbg.file.FileResult;import com.github.unidbg.file.IOResolver;import com.github.unidbg.linux.android.AndroidEmulatorBuilder;import com.github.unidbg.linux.android.AndroidResolver;import com.github.unidbg.linux.android.dvm.*;import com.github.unidbg.linux.android.dvm.api.ClassLoader;import com.github.unidbg.memory.Memory;import com.github.unidbg.pointer.UnidbgPointer;import com.github.unidbg.utils.Inspector;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintStream;import java.util.ArrayList;import java.util.List;public class YZWG extends AbstractJni implements IOResolver {    public static AndroidEmulator emulator;    public static Memory memory;    public static VM vm;    public static Module module;    @Override    public FileResult resolve(Emulator emulator, String pathname, int oflags) {        System.out.println("sana file open-->>" + pathname);        return null;    }    public YZWG() {        emulator = AndroidEmulatorBuilder                .for64Bit()                .setProcessName("com.hpbr.bosszhipin")                .addBackendFactory(new Unicorn2Factory(false))                .build();        // 文件访问 注意这里的处理,加上这一句        emulator.getSyscallHandler().addIOResolver(this);        memory = emulator.getMemory();        memory.setLibraryResolver(new AndroidResolver(23));        vm = emulator.createDalvikVM(new File("src/test/java/com/Samples/boss/files/BOSS直聘v13.141.apk"));        // 虚拟模块 添加这个就可以//        new AndroidModule(emulator, vm).register(memory);        vm.setJni(this);        vm.setVerbose(true);        DalvikModule dm = vm.loadLibrary(new File("src/test/java/com/Samples/boss/files/libyzwg.so"), true);        module = dm.getModule();        dm.callJNI_OnLoad(emulator);    }    public static void main(String[] args) {        YZWG demo = new YZWG();    }}

  • • 这里会报第一个错;
1
2
3

java.lang.UnsupportedOperationException: com/twl/signer/YZWG->gContext:Landroid/content/Context;    at com.github.unidbg.linux.android.dvm.AbstractJni.getStaticObjectField(AbstractJni.java:103)    at com.github.unidbg.linux.android.dvm.AbstractJni.getStaticObjectField(AbstractJni.java:53)

  • • 这个简单的我不说了;
1
2
3
4
5
6
7
8
9

@Overridepublic DvmObject<?> getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {    switch (signature){        case "com/twl/signer/YZWG->gContext:Landroid/content/Context;":{            return vm.resolveClass("android/content/Context").newObject(signature);        }    }    return super.getStaticObjectField(vm, dvmClass, signature);}

  • • 继续执行;
1
2
3

java.lang.UnsupportedOperationException: android/content/pm/PackageManager->getPackagesForUid(I)[Ljava/lang/String;    at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethod(AbstractJni.java:937)    at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethod(AbstractJni.java:871)

  • • 这个也直接补,实际上是获取包名,直接返回也未尝不可;
1
2
3
4
5
6
7
8
9
10
11

@Overridepublic DvmObject<?> callObjectMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {    switch (signature){        case "android/content/pm/PackageManager->getPackagesForUid(I)[Ljava/lang/String;":{            System.out.println("[+]sana getPackagesForUid uid-->>" + varArg.getIntArg(0));            return new ArrayObject(new StringObject(vm, vm.getPackageName()));        }    }    return super.callObjectMethod(vm, dvmObject, signature, varArg);}

  • • 继续执行;
1
2
3

java.lang.UnsupportedOperationException: java/lang/String->hashCode()I    at com.github.unidbg.linux.android.dvm.AbstractJni.callIntMethod(AbstractJni.java:969)    at com.github.unidbg.linux.android.dvm.AbstractJni.callIntMethod(AbstractJni.java:942)

  • • 这个获取一个hashcode,后续可能会用上,可以留意一下;
1
2
3
4
5
6
7
8
9
10

@Overridepublic int callIntMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {    switch (signature){        case "java/lang/String->hashCode()I":{            int value = dvmObject.getValue().hashCode();            return value;        }    }    return super.callIntMethod(vm, dvmObject, signature, varArg);}

  • • 到这里就没有环境问题了,可以开始call了;
1
2
3
4
5
6
7

RegisterNative(com/twl/signer/YZWG, nativeEncodePassword(Ljava/lang/String;)Ljava/lang/String;, RX@0x4001f650[libyzwg.so]0x1f650)RegisterNative(com/twl/signer/YZWG, nativeEncodeData([BLjava/lang/String;)Ljava/lang/String;, RX@0x400200c0[libyzwg.so]0x200c0)RegisterNative(com/twl/signer/YZWG, nativeEncodeRequest([BLjava/lang/String;)Ljava/lang/String;, RX@0x400209a4[libyzwg.so]0x209a4)RegisterNative(com/twl/signer/YZWG, nativeSignature([BLjava/lang/String;)[B, RX@0x40021864[libyzwg.so]0x21864)RegisterNative(com/twl/signer/YZWG, nativeDecodeContent(Ljava/lang/String;Ljava/lang/String;)[B, RX@0x40022ad0[libyzwg.so]0x22ad0)RegisterNative(com/twl/signer/YZWG, nativeDecodeContent([BLjava/lang/String;III)[B, RX@0x40024dc8[libyzwg.so]0x24dc8)RegisterNative(com/twl/signer/YZWG, nativeDecodePassword(Ljava/lang/String;)[B, RX@0x4001fb4c[libyzwg.so]0x1fb4c)

  • • 参数就用之前给出的那一个吧;一共两个参数,这里用api来调用,比较方便;
1
2
3
4
5
6
7
8
9
10
11
12
13

public void call_sig() {    byte[] bArr = "/api/batch/batchRunV2batch_method_feed=%5B%22method%3Dzpgeek.app.geek.search.cardlist%26encryptExpectId%3D4617621d9b2479b31nZ82tu0FFRSwA%257E%257E%26expectId%3D1261694622%26filterParams%3D%257B%2522cityCode%2522%253A%2522101010100%2522%252C%2522chattedJob%2522%253A0%252C%2522switchCity%2522%253A0%252C%2522labelFilter%2522%253A%257B%2522tags%2522%253A%255B%257B%2522code%2522%253A%2522-1%2522%252C%2522tag%2522%253A%2522%25E4%25B8%258D%25E9%2599%2590%2522%257D%255D%252C%2522type%2522%253A2%257D%257D%26isFromJd%3D0%26isSupplySearch%3Dfalse%26jids%3D%26maskComType%3D0%26naturalLanguageParam%3D%26noCorrect%3D0%26page%3D1%26prefix%3Dh%26pushId%3D%26pushType%3D%26query%3Dpython%26queryId%3D%26queryTitle%3D%25E6%2590%259C%25E7%25B4%25A2%25E5%258F%2591%25E7%258E%25B0%26searchType%3D3%26sort%3D-1%26source%3D1%26sugAbKey%3DM69-GroupA%26sugSessionId%3D1VpO529c1Ho%26userIntent%3D%22%2C+%22method%3Dzpgeek.app.search.listad.query%26encryptExpectId%3D4617621d9b2479b31nZ82tu0FFRSwA%257E%257E%26filterParams%3D%257B%2522cityCode%2522%253A%2522101010100%2522%252C%2522chattedJob%2522%253A0%252C%2522switchCity%2522%253A0%252C%2522labelFilter%2522%253A%257B%2522tags%2522%253A%255B%257B%2522code%2522%253A%2522-1%2522%252C%2522tag%2522%253A%2522%25E4%25B8%258D%25E9%2599%2590%2522%257D%255D%252C%2522type%2522%253A2%257D%257D%26page%3D1%26query%3Dpython%26sort%3D-1%22%5D&client_info=%7B%22version%22%3A%2212%22%2C%22os%22%3A%22Android%22%2C%22start_time%22%3A%221771739823352%22%2C%22resume_time%22%3A%221771739823352%22%2C%22channel%22%3A%2228%22%2C%22model%22%3A%22google%7C%7CPixel+6%22%2C%22dzt%22%3A0%2C%22loc_per%22%3A0%2C%22uniqid%22%3A%223880525a-bdb9-41fb-b8bc-b38d1addd229%22%2C%22oaid%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22oaid_honor%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22did%22%3A%22DUYlEEPTkR_1kujGVuif0etPK8a41fRRHAa0RFVZbEVFUFRrUl8xa3VqR1Z1aWYwZXRQSzhhNDFmUlJIQWEwc2h1%22%2C%22tinker_id%22%3A%22Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09%22%2C%22is_bg_req%22%3A0%2C%22network%22%3A%22wifi%22%2C%22operator%22%3A%22UNKNOWN%22%2C%22abi%22%3A1%7D&curidentity=0&req_time=1771741084302&uniqid=3880525a-bdb9-41fb-b8bc-b38d1addd229&v=13.141".getBytes();    // 调用静态native方法    DvmObject<?> result = YZWG.callStaticJniMethodObject(            emulator,            "nativeSignature([BLjava/lang/String;)[B",            bArr,            null    );    //获取并返回结果    byte[] res = (byte[]) result.getValue();    System.out.println("[+]call_sig result:" + new String(res, StandardCharsets.UTF_8));}

  • • 直接就有结果,而且和抓包是对得上的;
1
2
3

[+]call_sig result:     V3.0f28a35d5baff6f9c44f199a292bece55抓包:V3.0f28a35d5baff6f9c44f199a292bece55

  • • 再继续call sp参数吧;
1
2
3
4
5
6
7
8
9
10
11
12
13

public void call_sp(){    byte[] bArr1 = "batch_method_feed=%5B%22method%3Dzpgeek.app.geek.search.cardlist%26encryptExpectId%3D4617621d9b2479b31nZ82tu0FFRSwA%257E%257E%26expectId%3D1261694622%26filterParams%3D%257B%2522cityCode%2522%253A%2522101010100%2522%252C%2522chattedJob%2522%253A0%252C%2522switchCity%2522%253A0%252C%2522labelFilter%2522%253A%257B%2522tags%2522%253A%255B%257B%2522code%2522%253A%2522-1%2522%252C%2522tag%2522%253A%2522%25E4%25B8%258D%25E9%2599%2590%2522%257D%255D%252C%2522type%2522%253A2%257D%257D%26isFromJd%3D0%26isSupplySearch%3Dfalse%26jids%3D%26maskComType%3D0%26naturalLanguageParam%3D%26noCorrect%3D0%26page%3D1%26prefix%3Dh%26pushId%3D%26pushType%3D%26query%3Dpython%26queryId%3D%26queryTitle%3D%25E6%2590%259C%25E7%25B4%25A2%25E5%258F%2591%25E7%258E%25B0%26searchType%3D3%26sort%3D-1%26source%3D1%26sugAbKey%3DM69-GroupA%26sugSessionId%3D1VpO529c1Ho%26userIntent%3D%22%2C+%22method%3Dzpgeek.app.search.listad.query%26encryptExpectId%3D4617621d9b2479b31nZ82tu0FFRSwA%257E%257E%26filterParams%3D%257B%2522cityCode%2522%253A%2522101010100%2522%252C%2522chattedJob%2522%253A0%252C%2522switchCity%2522%253A0%252C%2522labelFilter%2522%253A%257B%2522tags%2522%253A%255B%257B%2522code%2522%253A%2522-1%2522%252C%2522tag%2522%253A%2522%25E4%25B8%258D%25E9%2599%2590%2522%257D%255D%252C%2522type%2522%253A2%257D%257D%26page%3D1%26query%3Dpython%26sort%3D-1%22%5D&client_info=%7B%22version%22%3A%2212%22%2C%22os%22%3A%22Android%22%2C%22start_time%22%3A%221771739823352%22%2C%22resume_time%22%3A%221771739823352%22%2C%22channel%22%3A%2228%22%2C%22model%22%3A%22google%7C%7CPixel+6%22%2C%22dzt%22%3A0%2C%22loc_per%22%3A0%2C%22uniqid%22%3A%223880525a-bdb9-41fb-b8bc-b38d1addd229%22%2C%22oaid%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22oaid_honor%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22did%22%3A%22DUYlEEPTkR_1kujGVuif0etPK8a41fRRHAa0RFVZbEVFUFRrUl8xa3VqR1Z1aWYwZXRQSzhhNDFmUlJIQWEwc2h1%22%2C%22tinker_id%22%3A%22Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09%22%2C%22is_bg_req%22%3A0%2C%22network%22%3A%22wifi%22%2C%22operator%22%3A%22UNKNOWN%22%2C%22abi%22%3A1%7D&curidentity=0&req_time=1771741084302&uniqid=3880525a-bdb9-41fb-b8bc-b38d1addd229&v=13.141".getBytes();    //调用静态native方法    DvmObject<?> result = YZWG.callStaticJniMethodObject(            emulator,            "nativeEncodeRequest([BLjava/lang/String;)Ljava/lang/String;",            bArr1,            null    );    //获取并返回结果    String res = (String) result.getValue();    System.out.println("[+]call_sp result:" + res);}

  • • 太长了,不写出结果了,也是不用再补环境,直接就有结果,而且和抓包对得上;
  • • 顺便把返回值的调用也写了,这个也不需要补环境,但是数据太占篇幅了,不写了;不过这里需要注意几个点,首先是原始返回值太长了,我们需要寻找短一点的来调用;并且不同的长度最后一个int参数是不一样的;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

public void decode_response() {    byte[] bArr = {-10, 114, 76, 25, 44, -37, 100, 101, -128, -89, 82, -77, -46, -79, -105, 125, -105, -32, -97, 119, 58, 83, -13, -111, -30, -102, -103, -4, -64, 116, 71, 21, -99, 2, -95, 113, -79, 114, 8, 37, 105, 120};    int i11 = 0;    int i12 = 1;    int i13 = 0;    // 短的是0 长的是2    //调用静态native方法    DvmObject<?> result = YZWG.callStaticJniMethodObject(            emulator,            "nativeDecodeContent([BLjava/lang/String;III)[B",            bArr,            null,            i11,            i12,            i13    );    //获取并返回结果    byte[] res3 = (byte[]) result.getValue();    System.out.println("result: " + new String(res3));}

  • • 到这里基础的准备就都做好了,可以开始算法分析了;

4. 算法分析

4.1 sig

  • • 先来分析sig参数,把其他两个调用先停了,老规矩,打开memcpy的hook;并且把密文结果转成hexdump,方便分析;
1
2

00000000  66 32 38 61 33 35 64 35 62 61 66 66 36 66 39 63  |f28a35d5baff6f9c|00000010  34 34 66 31 39 39 61 32 39 32 62 65 63 65 35 35  |44f199a292bece55|

  • • memcpy的一部分日志:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

>-----------------------------------------------------------------------------<[16:19:06 757]目标: 40713060 来源(主要追这里): bfffef1a lr 40578dc4, md5=3667f6a0c97490758d7dc9659d01ea34, hex=6632size: 20000: 66 32                                              f2^-----------------------------------------------------------------------------^>-----------------------------------------------------------------------------<[16:19:06 758]目标: 40713062 来源(主要追这里): bfffef1a lr 40578dc4, md5=8edd87c407c4a1732e4924598236e319, hex=3861size: 20000: 38 61                                              8a^-----------------------------------------------------------------------------^>-----------------------------------------------------------------------------<[16:19:06 758]目标: 40713064 来源(主要追这里): bfffef1a lr 40578dc4, md5=1c383cd30b7c298ab50293adfecb7b18, hex=3335size: 20000: 33 35                                              35^-----------------------------------------------------------------------------^

  • • 可以发现一些蛛丝马迹,那可以去找一下写入位置的信息;
1

emulator.traceWrite(0xbfffef1aL, 0xbfffef1aL + 0x10);

  • • pc是libc的函数,这种一般就不太好继续追了,可以打开unidbg的libc看看是什么函数,它实际上是一个_vfprintf函数;
  • • 这里需要另辟蹊径,回去看最后的日志;
1
2

JNIEnv->SetByteArrayRegion([B@0x000000000000000000000000000000000000000000000000000000000000000000000000, 0, 36, RW@0x40713090) was called from RX@0x40021fdc[libyzwg.so]0x21fdc[+]call_sig result:V3.0f28a35d5baff6f9c44f199a292bece55

  • • 去追一下0x21fdc这个位置;
  • • 第一眼确实看不出来什么,但这里我们追的是SetByteArrayRegion,这里并没有看到,那么v8基本上就是jnienv,+1664实际上是偏移,我们改一下类型就可以看出来了;
  • • 最后一个参数是源数据指针,所以去找它,v29又等于v27,所以去hook sub_1C38C这个函数;他一共有两个参数;
  • • 参数1看起来应该是前缀,参数2则是结果,那还需要继续追,也就是去hook 0x1C714这个函数;它也是两个参数,并且我们需要去看它的返回值;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

mx0 0x8a6>-----------------------------------------------------------------------------<[16:30:02 318]x0=RW@0x40719000, hex=2f617069·····261746368size: 22140000: 2F 61 70 69 2F 62 61 74 63 68 2F 62 61 74 63 68    /api/batch/batch·····这一部分数据省略了·····这一部分数据省略了0810: 4E 4B 4E 4F 57 4E 25 32 32 25 32 43 25 32 32 61    NKNOWN%22%2C%22a0820: 62 69 25 32 32 25 33 41 31 25 37 44 26 63 75 72    bi%22%3A1%7D&cur0830: 69 64 65 6E 74 69 74 79 3D 30 26 72 65 71 5F 74    identity=0&req_t0840: 69 6D 65 3D 31 37 37 31 37 34 31 30 38 34 33 30    ime=1771741084300850: 32 26 75 6E 69 71 69 64 3D 33 38 38 30 35 32 35    2&uniqid=38805250860: 61 2D 62 64 62 39 2D 34 31 66 62 2D 62 38 62 63    a-bdb9-41fb-b8bc0870: 2D 62 33 38 64 31 61 64 64 64 32 32 39 26 76 3D    -b38d1addd229&v=0880: 31 33 2E 31 34 31 61 33 30 38 66 33 36 32 38 62    13.141a308f3628b0890: 33 66 33 39 66 37 64 33 35 63 64 65 62 65 62 36    3f39f7d35cdebeb608A0: 39 32 30 65 32 31                                  920e21

  • • 返回值需要下一个blr断点去看当时的x0;
  • • 是结果无疑,并且参数是我们传递的东西,但是结尾附加了一点东西,a308f3628b3f39f7d35cdebeb6920e21;
  • • 看起来是一个盐,先不讨论他是否固定,先分析一下算法,32位的结果我很难不往那方面想;去测试一下;
  • • 我们猜的不错,sig是一个加盐的md5算法,往深处稍微跟一下也可以看到关键的md5_transform函数;
  • • 我分析了一下,应该是固定写死的,具体的位置是这块;
  • • 在内存里dump确实是 a308f3628b3f39f7d35cdebeb6920e21 这个值,交叉引用发现整个函数是在jni_onload被调用的,大概率是ollvm的字符串解密函数,这里我先不管了,有兴趣的可以跟一下;
  • • 所以sig= V3.0+md5(urlpath+请求参数),请求参数有url编码,好像还是两层,复现的时候需要注意;

4.2 sp

  • • 接下来分析sp,在分析我们最好是做一点简单的拆解,这么长的密文,大概率不会是哈希,极有可能是对称加密,要么是分组要么是流加密;无论哪种,我们都不希望分析的时候有非常多的分组,所以我在开始分析前将明文改成短一点的形式,改成什么无所谓,就用我前面的 call 就好,短一点比较好分析,而且我们验证过了unidbg跑出来结果是没问题的;
  • • 执行结果:
1
2

JNIEnv->NewStringUTF("zwp_NCTRJTSwi3DepMLkHOGFvU0aAIbycf2I7pY7DTCAI7RtvzRtOHFggw~~") was called from RX@0x40021020[libyzwg.so]0x21020[+]call_sp result:zwp_NCTRJTSwi3DepMLkHOGFvU0aAIbycf2I7pY7DTCAI7RtvzRtOHFggw~~

  • • 去追这个地址,0x21020;
  • • 和前面是是一个意思,自己改一下jnienv类型;
  • • 先hook 1CEB8看看;它有两个参数,第二个是一个长度;
  • • 这是一个base64的数据,看看返回值是什么;
  • • 返回值就是最终的结果,那么这个函数只是把base64数据做了一点处理;
1
2
3

/ -> _+ ->-= -> ~

  • • 那它前面的sub_29E90函数大概率就是base64函数了;继续hook看看,它有三个参数,参数1是缓冲区,参数3是长度,应该是参数2的长度;
  • • 看看返回值;
  • • 确实是base64的结果,我们去看看是不是标准的base64;
  • • 是标准base64无疑,所以接下来的问题就在于这段明文是什么?
1
2
3

0000: CF 0A 7F 34 24 D1 25 34 B0 8B 70 DE A4 C2 E4 1C    ...4$.%4..p.....0010: E1 85 BD 4D 1A 00 86 F2 71 FD 88 EE 96 3B 0D 30    ...M....q....;.00020: 80 23 B4 6D BF 34 6D 38 71 60 83                   .#.m.4m8q`.

  • • 往上看就可以看到sub_2E91C有相关的内容;
  • • hook看看情况,他一共有四个参数,参数二和三是一样的;参数四是0x2b;
  • • 看起来都不是特别眼熟,再看看结果吧;
  • • 结果确实是我们需要找的base64的明文那一部分,没有什么可看的了,进这个函数看看吧;
  • • 总体不长,稍微熟悉一点的朋友应该能看出来是什么算法;
1

*(data2 + v11) = (~v9 & 0x7B | v9 & 0x84) ^ (~*(data + v11) & 0x7B | *(data + v11) & 0x84)

  • • 这一行是用作混淆的,化简一下实际上就等于:
1

*(data2 + v11) = v9 ^ *(data + v11)

  • • 不仅是异或,还有256,循环退出条件也是明文长度,他应该是一个rc4算法;
1
2
3
4
5
6
7
8
9
10
11

void rc4_enc(unsigned char *S_Box, char *data, int data_len){    int i = 0, j = 0, t = 0;    for (int k = 0; k < data_len; k++) {        i = (i + 1) % 256;        j = (j + S_Box[i]) % 256;        swap(S_Box[i], S_Box[j]);        t = (S_Box[i] + S_Box[j]) % 256;        data[k] = data[k] ^ S_Box[t];    }}

  • • 其实是比较相似的了,参数1应该就是S盒,参数2、3就应该是明文;
  • • 还应该有一个打乱s盒的函数,想必就是上面这个sub_2E680函数了;
  • • hook看看,有三个参数,参数1不知道,参数2应该是key、参数3是key的长度;
  • • 是否有些眼熟,这个key是前面sig的盐;那我们测试一下结果是否是我们所想的那样;
  • • 确实是标准的rc4算法,所以base64的明文就来自于rc4算法的加密结果;这个key想必也是对照的,那么,rc4的明文又是什么?
  • • 虽然看起来和我们的明文差不多,但是还是有区别的;
1
2
3

0000: 42 5A 50 42 6C 6F 63 6B 00 00 00 00 13 00 00 00    BZPBlock........0010: 11 00 00 00 02 00 00 00 F0 02 62 61 74 63 68 5F    ..........batch_0020: 6D 65 74 68 6F 64 5F 66 65 65 64                   method_feed

  • • 明文是:batch_method_feed,看起来差不多;找一下这一部分怎么来的,去看看交叉引用;
  • • 前面两个看起来比较有可能一点,进去看看;
  • • 有个j_LZ4_compressBound函数,这是LZ4压缩的标志,搜索一下这个函数是什么;
1

int LZ4_compressBound(int inputSize);

  • • 作用:计算给定输入字节数 inputSize 经 LZ4 压缩后可能产生的最大输出尺寸;
  • • hook一下sub_1D444函数看看,毕竟有目标;他一共有四个参数;后面两个都是长度,参数3应该是明文的长度;
  • • x1是缓冲区,运行结束后确实是我们要找的那一部分数据,进去函数内部看看;
  • • 一进来就可以看到一个LZ4的函数,结合前面的符号我们猜测可能是一个LZ4压缩,我们尝试去压缩一下看看是否是标准的;
  • • 看起来并不一致,熟悉压缩算法的朋友应该知道,压缩算法都有一个魔数,用于分辨是哪一个压缩算法;
  • • LZ4是4字节,小端,值为0x184D2204,可以和标准的对比看看,确实是这样;但是我们的结果很明显不一样,这里我们让ai描述一下LZ4压缩后的组成;
  • • 结果属于是完全不对了,应该是魔改了这部分,看看代码部分吧,我写了一点点注释;
  • • 压缩成功后的结果并没有放在a2的位置,而是往后挪了24个字节,然后自定义了24 字节头部;
  • • 解析一下这部分自定义,其实就在下方高亮处;先是8 字节魔数(非标准),也就是固定的0x6B636F6C42505A42,这里是小端序的,然后是4 字节保留字段(置 0),压缩后长度(4 字节),然后是原始数据长度(4 字节),再就是原始长度 ^ 压缩长度(4 字节校验);
  • • 汇总一下:
    • • 偏移 0:8 字节魔数 42 5a 50 42 6c 6f 63 6b(固定);
    • • 偏移 8:4 字节保留字段(置 0);
    • • 偏移 12:压缩后长度v12(4 字节);
    • • 偏移 16:原始数据长度v5(4 字节);
    • • 偏移 20:原始长度 ^ 压缩长度(4 字节);
  • • 实际上这个压缩只是改了头部那一部分,其他的还是标准的,所以我们如果需要解压缩的话需要去掉对应的24字节,然后再解压缩;这一部分我踩坑了,传参出问题了导致一直出错,搞得我还以为不是标准的压缩;
  • • 稍微总结一下sp的算法:
    • • 首先是LZ4压缩明文,但是这里改了一点头部拼接,就在上面有具体改了什么;
    • • lz4压缩后进行RC4加密,秘钥是sig那个盐:a308f3628b3f39f7d35cdebeb6920e21;
    • • 最后进行base64编码,码表稍微有点改动,也可以标准编码后替换那几个符号;
  • • 这个需要了解LZ4压缩的细节,我也不是特别熟悉,放一个解密sp的demo在这,可以自行测试;
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

import base64import structimport lz4.blockfrom Crypto.Cipher import ARC4def base64_decode_custom(b64_str: str) -> bytes:    """    自定义Base64解码(码表: A-Za-z0-9-_~)    """    BASE64_ALLOWED = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_~"    cleaned = ''.join(c for c in b64_str if c in BASE64_ALLOWED).replace('~', '=')    cleaned += '=' * ((4 - len(cleaned) % 4) % 4)    return base64.urlsafe_b64decode(cleaned.encode())def rc4_decrypt(data_bytes: bytes, key_hex: str = "a308f3628b3f39f7d35cdebeb6920e21") -> bytes:    key_bytes = key_hex.encode()    return ARC4.new(key_bytes).decrypt(data_bytes)def lz4_decompress_custom(packed_data: hex) -> bytes:    """    还原 sub_1D444:解析头部 + LZ4解压    :param packed_data: 封装后的压缩数据    :return: 原始明文    """    if len(packed_data) < 24:        raise ValueError("数据太短")    magic, _, comp_len, orig_len, chk = struct.unpack('<QIIII', bytes.fromhex(packed_data)[:24])    if magic != 0x6B636F6C42505A42 or chk != (orig_len ^ comp_len):        raise ValueError("校验失败:非目标格式或数据损坏")    compressed = bytes.fromhex(packed_data)[24:24 + comp_len]    return lz4.block.decompress(compressed, uncompressed_size=orig_len)if __name__ == "__main__":    B64_STRING = "xxx"    decoded = base64_decode_custom(B64_STRING)    decrypted = rc4_decrypt(decoded)    result = lz4_decompress_custom(decrypted.hex())    print(result.decode())

  • • 所以sp=base64( RC4 (魔改LZ4压缩 (urlpath+请求参数) ) ),总体就是这个压缩可能费点时间,剩下的就是响应的解密了;

4.3 响应解密

  • • 直接调用函数,看看有没有什么信息吧;
  • • 信息不多,但是还是有一点,这个0xf6724c192c是什么?感觉应该是密文的十六进制,转一下看看;
  • • 确实是这样,那去看一下0x25440这个地址;
  • • 进来还是自己把类型改正一下,正好落在整个解密函数里,大概有几百行,我们稍微看看吧;把鼠标放在参数1上,看看交叉引用;
  • • 我个人觉得获取长度和它本身是比较敏感的操作,也就是下面这三个地方;
  • • 可以都去看看,有没有什么关键的信息;
  • • 不断地找交叉引用配合变量名的修改就好,找到这样一个位置有函数调用;
  • • 看起来sub_23F2C和sub_242A0可能会是目标,进sub_23F2C看看;
  • • 记忆力好一点的朋友应该能看出来这是哪里,先不表,hook看看是不是走了;他一共有4个参数,参数1是1,参数2、3应该是地址;
  • • 参数2很显然是我们的明文,参数3是rc4的key,那这个函数是不是rc4呢?答案是显然的;
  • • 去解一下吧;
  • • 所以响应的算法实际上和sp是反着来的,sp加密响应解密,但是响应是没有base64的过程的;其实在分析之前我就知道大概是一样的算法了,我们抓包的响应结果的开头是:
    • 把它前面几个字节base64一下;
  • • 而且在分析sp的时候多次有这种开头的hex数据,如下图:
  • • 这都是可以猜测的,这里就聊这么多,算法还没有完全结束;
  • • 这个数据只是经过了rc4解密,但是没有lz4解压缩的内容,别忘了我们的结果其实很长的;可以把参数换成长的再调用一下;
  • • idea显示方法太长了,我这会又没写加密函数,直接去看另一个方法吧;
  • • 实际上就是在解密前解一次压缩,其余没啥区别,这里也没有base64;
  • • 就用前面那个sp解密的脚本也可以解开长的密文;
  • • 到这里三个位置的算法都讲清楚了,响应解密和sp是类似的逆过程;

5. 总结

  • • 除了这一种密文以外,我还发现了有多种密文,我以sp和响应对照着说一下:
1
2
3
4
5
6
7
8
9

本文讲的:sp:zwp_N开头响应:cf 0a 7f 34开头 响应还有一种短的 开头不记得了sp:wxJRBAfMjnn开头响应:c3 12 51 04开头sp:wxJRBAfMjnn开头响应:fa 6a 62 29开头 这个属于短的 和前面的理论一样 没有压缩 只有rc4解密

  • • 大概就是四种,有可能更多,毕竟我也只是随便看了几个接口;后面这种其实算法什么都是一样的,就是rc4的key不一样,也不能说不一样,多了点东西而已,感兴趣的自己看看就好;
  • • 总结一下这几个参数:
    • • sig:md5加盐,盐是rc4的key;
    • • sp:base64 + rc4 + lz4压缩;
    • • 响应:同sp;
  • • 致谢:样本来源于我的好朋友小风的知识星球;
  • • 此样本在我的知识星球里,另有一些案例文章,有兴趣的话请后台私信或+我vx:HeiYuKuaiDou23;
基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-13 22:10:11 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/620543.html
  2. 运行时间 : 0.150786s [ 吞吐率:6.63req/s ] 内存消耗:4,861.53kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=f22c6f239ef9bc45afdd5da7e20de181
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000546s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000771s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000336s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000316s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000558s ]
  6. SELECT * FROM `set` [ RunTime:0.000269s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000601s ]
  8. SELECT * FROM `article` WHERE `id` = 620543 LIMIT 1 [ RunTime:0.000702s ]
  9. UPDATE `article` SET `lasttime` = 1778681411 WHERE `id` = 620543 [ RunTime:0.016151s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000289s ]
  11. SELECT * FROM `article` WHERE `id` < 620543 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000519s ]
  12. SELECT * FROM `article` WHERE `id` > 620543 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.006431s ]
  13. SELECT * FROM `article` WHERE `id` < 620543 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.003694s ]
  14. SELECT * FROM `article` WHERE `id` < 620543 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000999s ]
  15. SELECT * FROM `article` WHERE `id` < 620543 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.014801s ]
0.154677s