计算机技术
微信跳一跳抓包修改分数-Java实现

原改分代码为Python代码,
1 2 3 4 5 6 7 8 9 |
#!/usr/bin/python # -*- coding: utf-8 -*- print(“Hello World!”) import requests import json import time from Crypto.Cipher import AES import base64 |
以上代码来自https://zhuanlan.zhihu.com/p/32473340
考虑到很多同学没有Python环境,用起来并不是很方便,故参考此代码改写成Java版本。
另外简单写了个Web版提交工具,
http://java.zhaoxuyang.com/WxTyT/ (2018年1月3日 19:20,测试可用。)
但是不管哪种方法,都需要手动抓取微信跳一跳小游戏的session_id,抓包方法可以参考下面的或者自行搜索相关资料。
安卓抓包参考:安卓下使用Packet Capture抓取微信跳一跳小游戏的session_id值
iOS抓包参考:iOS下抓取微信跳一跳小游戏的session_id值
Java实现:
这里写了两个类,一个PKCS7加密的单独类,(参考自 WindCoder)
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
package com; import javax.crypto.Cipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; public class Pkcs7Encoder { // 算法名称 static final String KEY_ALGORITHM = “AES”; // 加解密算法/模式/填充方式 static final String algorithmStr = “AES/CBC/PKCS7Padding”; private static Key key; private static Cipher cipher; boolean isInited = false; //默认对称解密算法初始向量 iv static byte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 }; public static void init(byte[] keyBytes) { // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyBytes.length % base != 0) { int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length); keyBytes = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); // 转化成JAVA的密钥格式 key = new SecretKeySpec(keyBytes, KEY_ALGORITHM); try { // 初始化cipher cipher = Cipher.getInstance(algorithmStr, “BC”); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchPaddingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchProviderException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 加密方法 * –使用默认iv时 * @param content * 要加密的字符串 * @param keyBytes * 加密密钥 * @return */ public static byte[] encrypt(byte[] content, byte[] keyBytes) { byte[] encryptedText = encryptOfDiyIV(content,keyBytes,iv); return encryptedText; } /** * 解密方法 * –使用默认iv时 * @param encryptedData * 要解密的字符串 * @param keyBytes * 解密密钥 * @return */ public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) { byte[] encryptedText = decryptOfDiyIV(encryptedData,keyBytes,iv); return encryptedText; } /** * 加密方法 * —自定义对称解密算法初始向量 iv * @param content * 要加密的字符串 * @param keyBytes * 加密密钥 * @param ivs * 自定义对称解密算法初始向量 iv * @return 加密的结果 */ public static byte[] encryptOfDiyIV(byte[] content, byte[] keyBytes, byte[] ivs) { byte[] encryptedText = null; init(keyBytes); try { cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivs)); encryptedText = cipher.doFinal(content); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return encryptedText; } /** * 解密方法 * * @param encryptedData * 要解密的字符串 * @param keyBytes * 解密密钥 * @param ivs * 自定义对称解密算法初始向量 iv * @return */ public static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes,byte[] ivs) { byte[] encryptedText = null; init(keyBytes); try { cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs)); encryptedText = cipher.doFinal(encryptedData); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return encryptedText; } } |
执行请求的工具类
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 65 66 67 68 69 70 71 72 73 |
package com; import okhttp3.*; import org.bouncycastle.util.encoders.Base64; import org.json.JSONObject; import java.io.IOException; import java.io.UnsupportedEncodingException; /** * @author: Seayon * @date: 2017/12/31 * @time: 21:11 */ public class Util { private static final MediaType JSON = MediaType.parse(“application/json;charset=utf-8”); private static final String WXGAME_URL = “https://mp.weixin.qq.com/wxagame/wxagame_settlement”; public static final String SESSIONID_ERROR = “SESSIONID有误,请检查”; private static String getActionData(String sessionKey, String encryptedData, String iv) { byte[] sessionKeyBy = sessionKey.getBytes(); byte[] en = new byte[0]; try { en = encryptedData.getBytes(“UTF-8”); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } byte[] ivBy = iv.getBytes(); byte[] enc = Pkcs7Encoder.encryptOfDiyIV(en, sessionKeyBy, ivBy); return new String(Base64.toBase64String(enc)); } public static String postData(String score, String times, String session_id) { String result = null; String content = “{“score”: ” + score + “, “times”: ” + times + “}”; String AES_KEY = null; try { AES_KEY = session_id.substring(0, 16); } catch (Exception e) { return SESSIONID_ERROR; } String AES_IV = AES_KEY; OkHttpClient okHttpClient = new OkHttpClient(); String actionData = Util.getActionData(AES_KEY, content, AES_IV); String json = “{“base_req”:{“session_id”:”” + session_id + “”,”fast”:1},”action_data”:”” + actionData + “”}”; RequestBody requestBody = RequestBody.create(JSON, json); Request request = new Request.Builder() .url(WXGAME_URL) .header(“Accept”,”*/*”) .header(“Accept-Language”,”zh-cn”) .header(“User-Agent”,”Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E304 MicroMessenger/6.6.1 NetType/WIFI Language/zh_CN”) .header(“Content-Length”,”680″) .header(“Content-Type”,”application/json”) .header(“Referer”,”https://servicewechat.com/wx7c8d593b2c3a7703/5/page-frame.html”) .header(“Host”,”mp.weixin.qq.com”) .header(“Connection”,”keep-alive”) .post(requestBody) .build(); ResponseBody responseBody = null; try { responseBody = okHttpClient.newCall(request).execute().body(); result = responseBody.string(); } catch (IOException e) { e.printStackTrace(); } finally { if (responseBody != null) { responseBody.close(); } } return result; } } |
执行测试
1 2 3 4 5 6 7 8 |
public class Main { public static void main(String[] args) { String sessionid = “==”; String score = “100”; String times = “700”; String result = Util.postData(score, times, sessionid); System.out.println(result); } |
目前观察当执行errcode为0时代表成功,此时需要结束杀死微信的后台进程,重新进入微信,打开跳一跳小游戏,可以查看自己的分数,分数千万不要太高,我目前设置过的最高分是1024分,没有被封。
代码中使用到的依赖,Maven :
XHTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.11</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-debug-jdk15on</artifactId> <version>1.55</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20171018</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.9.1</version> </dependency> |
https://zhaoxuyang.com/%E5%BE%AE%E4%BF%A1%E8%B7%B3%E4%B8%80%E8%B7%B3%E6%8A%93%E5%8C%85%E6%94%B9%E5%88%86-java%E5%AE%9E%E7%8E%B0/