抖音逆向研究X-Gorgon,X-Khronos生成源碼 java

抖音逆向研究X-Gorgon,X-Khronos生成源碼 java

抖音的接口中,通過抓包抖音請求時,可以發現x-gorgon和 xlog兩大參數是必備的,雖然說目前有些接口不通過這兩個參數還是可以拿到數據,但是我覺得抖音已經預留顯示了這兩大請求的參數,只會逐步提高要求,用於服務器驗證,不然日後都無法請求到數據,通過工具逆向反編譯出了抖音app的源碼,發現下列這個位於類com.ss.sys.ces.gg.tt中,有這樣一個函數用於生成x-gorgon的值。

public static void init_gorgon()

{

com.bytedance.frameworks.baselib.network.http.e.j = new e.a()

{

public final Map<String, String> a(String paramAnonymousString, Map<String, List<String>> paramAnonymousMap)

{

HashMap localHashMap = new HashMap();

for (;;)

{

try

{

if ((!paramAnonymousString.toLowerCase().contains("http")) && (!paramAnonymousString.toLowerCase().contains("https"))) {

throw new NullPointerException("nein http/https");

}

if ((paramAnonymousString.toLowerCase().contains("X-Khronos")) && (paramAnonymousString.toLowerCase().contains("X-Gorgon"))) {

throw new NullPointerException("it was");

}

if (!tt.a(paramAnonymousString))

{

int i = (int)(System.currentTimeMillis() / 1000L);

paramAnonymousString = tt.b(paramAnonymousString);

localObject2 = null;

if ((paramAnonymousString != null) && (paramAnonymousString.length() > 0))

{

localObject1 = d.a(paramAnonymousString);

Iterator localIterator = paramAnonymousMap.entrySet().iterator();

paramAnonymousMap = null;

paramAnonymousString = paramAnonymousMap;

if (localIterator.hasNext())

{

Object localObject4 = (Map.Entry)localIterator.next();

localObject3 = localObject2;

if (((String)((Map.Entry)localObject4).getKey()).toUpperCase().contains("X-SS-STUB")) {

localObject3 = (String)((List)((Map.Entry)localObject4).getValue()).get(0);

}

localObject2 = localObject3;

if (!((String)((Map.Entry)localObject4).getKey()).toUpperCase().contains("COOKIE")) {

continue;

}

String str = (String)((List)((Map.Entry)localObject4).getValue()).get(0);

localObject2 = localObject3;

if (str == null) {

continue;

}

localObject2 = localObject3;

if (str.length() <= 0) {

continue;

}

localObject4 = d.a(str);

str = tt.c(str);

localObject2 = localObject3;

paramAnonymousMap = (Map<String, List<String>>)localObject4;

if (str == null) {

continue;

}

localObject2 = localObject3;

paramAnonymousMap = (Map<String, List<String>>)localObject4;

if (str.length() <= 0) {

continue;

}

paramAnonymousString = d.a(str);

StcSDKFactory.getInstance().setSession(str);

localObject2 = localObject3;

paramAnonymousMap = (Map<String, List<String>>)localObject4;

continue;

}

localObject3 = new StringBuilder();

((StringBuilder)localObject3).append(i);

localHashMap.put("X-Khronos", ((StringBuilder)localObject3).toString());

if (localObject1 == null) {

break label572;

}

localObject3 = localObject1;

if (((String)localObject1).length() == 0) {

break label572;

}

if (localObject2 == null) {

break label579;

}

localObject1 = localObject2;

if (((String)localObject2).length() == 0) {

break label579;

}

if (paramAnonymousMap == null) {

break label586;

}

localObject2 = paramAnonymousMap;

if (paramAnonymousMap.length() == 0) {

break label586;

}

if (paramAnonymousString == null) {

break label593;

}

paramAnonymousMap = paramAnonymousString;

if (paramAnonymousString.length() == 0) {

break label593;

}

if (b.a().a) {

Calendar.getInstance().getTimeInMillis();

}

paramAnonymousString = new StringBuilder();

paramAnonymousString.append((String)localObject3);

paramAnonymousString.append((String)localObject1);

paramAnonymousString.append((String)localObject2);

paramAnonymousString.append(paramAnonymousMap);

paramAnonymousString = com.ss.a.b.a.a(com.ss.sys.ces.a.leviathan(i, com.ss.a.b.a.a(paramAnonymousString.toString())));

if (b.a().a) {

Calendar.getInstance().getTimeInMillis();

}

localHashMap.put("X-Gorgon", paramAnonymousString);

return localHashMap;

}

}

else

{

throw new NullPointerException("filter_1");

}

}

catch (Throwable paramAnonymousString)

{

paramAnonymousString.getMessage().contains("filter_1");

return localHashMap;

}

Object localObject1 = null;

continue;

label572:

Object localObject3 = "00000000000000000000000000000000";

continue;

label579:

localObject1 = "00000000000000000000000000000000";

continue;

label586:

Object localObject2 = "00000000000000000000000000000000";

continue;

label593:

paramAnonymousMap = "00000000000000000000000000000000";

}

}

};

}

 

 

對應的就是底層.so文件了

通過分析知道,最終的x-gorgon的生成,是調用com.ss.sys.ces.a.leviathan函數,所以我們只要利用這個函數就能幫我們解決x-gorgon的生成,他裏面的參數有兩個

 public static native byte[] leviathan(int paramInt, byte[] paramArrayOfByte);

第一個是當前的時間戳,也就是X-Khronos

第二個字節組就一串字符串,由Url、postdata、cookies和sesseionid分別進行MD5加密組成的字串,做的二次請求。

所以也就發現了X-SS-STUB的值是將要post的數據做md5計算的值,如果是要做post的話,那這個值就需要帶上。就能正常請求到數據了。目前有了點小成果,具體細節就不公開了,如果對抖音相關技術感興趣,可加Q:1274140131一起探討

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章