当前位置:   article > 正文

Unidbg初步学习记录

unidbg

一、Unidbg安装和使用

参考:https://www.jianshu.com/p/59e08e48ac20

二、Unidbg案例学习,模拟调用so文件生成京东sign参数

抓包商品详情页,要模拟的是sign参数

先搭建基础框架代码:
  1. package com.kdd.test;
  2. import com.github.unidbg.AndroidEmulator;
  3. import com.github.unidbg.LibraryResolver;
  4. import com.github.unidbg.Module;
  5. import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
  6. import com.github.unidbg.linux.android.AndroidResolver;
  7. import com.github.unidbg.linux.android.dvm.*;
  8. import com.github.unidbg.memory.Memory;
  9. import org.apache.commons.logging.Log;
  10. import org.apache.commons.logging.LogFactory;
  11. import java.io.*;
  12. public class jd_main extends AbstractJni {
  13. private static final Log log = LogFactory.getLog(AbstractJni.class);
  14. public static void main (String[] args) throws IOException {
  15. jd_main RunLDQ =new jd_main();
  16. RunLDQ.runJni();
  17. RunLDQ.destroy();
  18. }
  19. private void destroy() throws IOException{
  20. emulator.close();
  21. System.out.println("destroy");
  22. }
  23. private static LibraryResolver createLibraryResolver() {
  24. return new AndroidResolver(23);
  25. }
  26. private static AndroidEmulator createARMEmulator() {
  27. return AndroidEmulatorBuilder
  28. .for32Bit()
  29. .build();
  30. }
  31. private final AndroidEmulator emulator;
  32. private final VM vm;
  33. private Module module;
  34. private DvmClass aBitmapkitUtils;
  35. //初始化
  36. public jd_main(){
  37. emulator = createARMEmulator();
  38. final Memory memory = emulator.getMemory();
  39. // 设置 sdk版本 23
  40. memory.setLibraryResolver(createLibraryResolver());
  41. //使用apk文件加载so的话,会自动处理签名方面的jni,具体可看AbstractJni,利用apk加载的好处,
  42. vm = emulator.createDalvikVM(new File("F:\\frida_learn_app\\jd\\jd-9.2.2.apk"));
  43. vm.setJni(this);
  44. // 是否打印日志
  45. vm.setVerbose(true);
  46. }
  47. public String runJni(){
  48. //加载apk的so
  49. DalvikModule dm = vm.loadLibrary("jdbitmapkit", false);
  50. //调用jni
  51. dm.callJNI_OnLoad(emulator);
  52. module = dm.getModule();
  53. return null;
  54. }

运行有报错补代码

  1. @Override
  2. public DvmObject<?> getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {
  3. switch (signature) {
  4. case "com/jingdong/common/utils/BitmapkitUtils->a:Landroid/app/Application;": {
  5. return vm.resolveClass("android/app/Activity", vm.resolveClass("android/content/ContextWrapper", vm.resolveClass("android/content/Context"))).newObject(null);
  6. }
  7. }
  8. return super.getStaticObjectField(vm, dvmClass, signature);
  9. }

报错补代码

  1. @Override
  2. public DvmObject<?> callObjectMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
  3. switch (signature) {
  4. case "android/app/Application->getPackageName()Ljava/lang/String;": {
  5. String packageName = vm.getPackageName();
  6. if (packageName != null) {
  7. return new StringObject(vm, packageName);
  8. }
  9. }
  10. }
  11. throw new UnsupportedOperationException(signature);
  12. }

报错补代码 

  1. @Override
  2. public DvmObject<?> newObject(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
  3. switch (signature) {
  4. case "sun/security/pkcs/PKCS7-><init>([B)V": {
  5. ByteArray array = varArg.getObjectArg(0);
  6. return new StringObject(vm, new String(array.getValue()));
  7. }
  8. }
  9. return super.newObject(vm, dvmClass, signature, varArg);
  10. }
基础环境没报错后,调用签名函数
  1. //加载so的哪个类
  2. aBitmapkitUtils = vm.resolveClass("com/jingdong/common/utils/BitmapkitUtils");
  3. //调用方法
  4. DvmObject<?> strRc = aBitmapkitUtils.callStaticJniMethodObject(emulator,"getSignFromJni()(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
  5. vm.addLocalObject(null),
  6. vm.addLocalObject(new StringObject(vm,"wareBusiness")),
  7. vm.addLocalObject(new StringObject(vm,"{\"abTest800\":true,\"avoidLive\":false,\"brand\":\"360\",\"cityId\":2144,\"darkModelEnum\":3,\"districtId\":24463,\"eventId\":\"Searchlist_Productid\",\"fromType\":0,\"isDesCbc\":true,\"latitude\":\"26.618816\",\"lego\":true,\"longitude\":\"106.644705\",\"model\":\"1605-A01\",\"ocrFlag\":false,\"pluginVersion\":90220,\"plusClickCount\":0,\"plusLandedFatigue\":0,\"provinceId\":\"24\",\"skuId\":\"10024083045618\",\"source_type\":\"search\",\"source_value\":\"鼠标垫小号\",\"townId\":51707,\"uAddrId\":\"0\"}")),
  8. vm.addLocalObject(new StringObject(vm,"uuid")),
  9. vm.addLocalObject(new StringObject(vm,"android")),
  10. vm.addLocalObject(new StringObject(vm,"9.2.2")));
  11. System.out.println(strRc.getValue());
  12. //获取返回值
  13. return (String) strRc.getValue();
后面有报错也是跟着报错补环境
最后成功运行出结果:

全部代码如下:
  1. package com.kdd.test;
  2. import com.github.unidbg.AndroidEmulator;
  3. import com.github.unidbg.LibraryResolver;
  4. import com.github.unidbg.Module;
  5. import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
  6. import com.github.unidbg.linux.android.AndroidResolver;
  7. import com.github.unidbg.linux.android.dvm.*;
  8. import com.github.unidbg.linux.android.dvm.Enumeration;
  9. import com.github.unidbg.linux.android.dvm.api.*;
  10. import com.github.unidbg.linux.android.dvm.api.ClassLoader;
  11. import com.github.unidbg.linux.android.dvm.array.ByteArray;
  12. import com.github.unidbg.memory.Memory;
  13. import org.apache.commons.logging.Log;
  14. import org.apache.commons.logging.LogFactory;
  15. import java.io.*;
  16. import java.security.MessageDigest;
  17. import java.security.cert.Certificate;
  18. import java.security.cert.CertificateEncodingException;
  19. import java.security.cert.CertificateException;
  20. import java.security.cert.CertificateFactory;
  21. import java.util.*;
  22. public class jd_main extends AbstractJni {
  23. private static final Log log = LogFactory.getLog(AbstractJni.class);
  24. public static void main (String[] args) throws IOException {
  25. jd_main RunLDQ =new jd_main();
  26. RunLDQ.runJni(args);
  27. RunLDQ.destroy();
  28. }
  29. private void destroy() throws IOException{
  30. emulator.close();
  31. System.out.println("destroy");
  32. }
  33. private static LibraryResolver createLibraryResolver() {
  34. return new AndroidResolver(23);
  35. }
  36. private static AndroidEmulator createARMEmulator() {
  37. return AndroidEmulatorBuilder
  38. .for32Bit()
  39. .build();
  40. }
  41. private final AndroidEmulator emulator;
  42. private final VM vm;
  43. private Module module;
  44. private DvmClass aBitmapkitUtils;
  45. //初始化
  46. public jd_main(){
  47. emulator = createARMEmulator();
  48. final Memory memory = emulator.getMemory();
  49. // 设置 sdk版本 23
  50. memory.setLibraryResolver(createLibraryResolver());
  51. //使用apk文件加载so的话,会自动处理签名方面的jni,具体可看AbstractJni,利用apk加载的好处,
  52. vm = emulator.createDalvikVM(new File("F:\\frida_learn_app\\jd\\jd-9.2.2.apk"));
  53. vm.setJni(this);
  54. // 是否打印日志
  55. // vm.setVerbose(true);
  56. }
  57. public String runJni(String[] args){
  58. //加载apk的so
  59. DalvikModule dm = vm.loadLibrary("jdbitmapkit", false);
  60. //调用jni
  61. dm.callJNI_OnLoad(emulator);
  62. module = dm.getModule();
  63. //加载so的哪个类
  64. aBitmapkitUtils = vm.resolveClass("com/jingdong/common/utils/BitmapkitUtils");
  65. //调用方法
  66. DvmObject<?> strRc = aBitmapkitUtils.callStaticJniMethodObject(emulator,"getSignFromJni()(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
  67. vm.addLocalObject(null),
  68. vm.addLocalObject(new StringObject(vm,"wareBusiness")),
  69. vm.addLocalObject(new StringObject(vm,"{\"abTest800\":true,\"avoidLive\":false,\"brand\":\"360\",\"cityId\":2144,\"darkModelEnum\":3,\"districtId\":24463,\"eventId\":\"Searchlist_Productid\",\"fromType\":0,\"isDesCbc\":true,\"latitude\":\"26.618816\",\"lego\":true,\"longitude\":\"106.644705\",\"model\":\"1605-A01\",\"ocrFlag\":false,\"pluginVersion\":90220,\"plusClickCount\":0,\"plusLandedFatigue\":0,\"provinceId\":\"24\",\"skuId\":\"10024083045618\",\"source_type\":\"search\",\"source_value\":\"鼠标垫小号\",\"townId\":51707,\"uAddrId\":\"0\"}")),
  70. vm.addLocalObject(new StringObject(vm,"uuid")),
  71. vm.addLocalObject(new StringObject(vm,"android")),
  72. vm.addLocalObject(new StringObject(vm,"9.2.2")));
  73. System.out.println(strRc.getValue());
  74. //获取返回值
  75. return (String) strRc.getValue();
  76. }
  77. @Override
  78. public DvmObject<?> getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {
  79. switch (signature) {
  80. case "com/jingdong/common/utils/BitmapkitUtils->a:Landroid/app/Application;": {
  81. return vm.resolveClass("android/app/Activity", vm.resolveClass("android/content/ContextWrapper", vm.resolveClass("android/content/Context"))).newObject(null);
  82. }
  83. }
  84. return super.getStaticObjectField(vm, dvmClass, signature);
  85. }
  86. @Override
  87. public DvmObject<?> newObject(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
  88. switch (signature) {
  89. case "sun/security/pkcs/PKCS7-><init>([B)V": {
  90. ByteArray array = varArg.getObjectArg(0);
  91. return new StringObject(vm, new String(array.getValue()));
  92. }
  93. }
  94. return super.newObject(vm, dvmClass, signature, varArg);
  95. }
  96. @Override
  97. public DvmObject<?> callObjectMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
  98. switch (signature) {
  99. case "android/app/Application->getPackageName()Ljava/lang/String;": {
  100. String packageName = vm.getPackageName();
  101. if (packageName != null) {
  102. return new StringObject(vm, packageName);
  103. }
  104. }
  105. }
  106. throw new UnsupportedOperationException(signature);
  107. }
  108. @Override
  109. public DvmObject<?> newObjectV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
  110. switch (signature) {
  111. case "java/lang/StringBuffer-><init>()V":{
  112. return vm.resolveClass("java/lang/StringBuffer").newObject(new StringBuffer());
  113. }
  114. case "java/lang/Integer-><init>(I)V" :{
  115. return vm.resolveClass("java/lang/Integer").newObject(new Integer(vaList.getIntArg(0)));
  116. }
  117. }
  118. throw new UnsupportedOperationException(signature);
  119. }
  120. @Override
  121. public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
  122. switch (signature) {
  123. case "android/app/Application->getAssets()Landroid/content/res/AssetManager;":
  124. return new AssetManager(vm, signature);
  125. case "android/app/Application->getClassLoader()Ljava/lang/ClassLoader;":
  126. return new ClassLoader(vm, signature);
  127. case "android/app/Application->getContentResolver()Landroid/content/ContentResolver;":
  128. return vm.resolveClass("android/content/ContentResolver").newObject(signature);
  129. case "java/util/ArrayList->get(I)Ljava/lang/Object;": {
  130. int index = vaList.getIntArg(0);
  131. ArrayListObject arrayList = (ArrayListObject) dvmObject;
  132. return arrayList.getValue().get(index);
  133. }
  134. case "android/app/Application->getSystemService(Ljava/lang/String;)Ljava/lang/Object;": {
  135. StringObject serviceName = vaList.getObjectArg(0);
  136. assert serviceName != null;
  137. return new SystemService(vm, serviceName.getValue());
  138. }
  139. case "java/lang/String->toString()Ljava/lang/String;":
  140. return dvmObject;
  141. case "java/lang/Class->getName()Ljava/lang/String;":
  142. return new StringObject(vm, ((DvmClass) dvmObject).getName());
  143. case "android/view/accessibility/AccessibilityManager->getEnabledAccessibilityServiceList(I)Ljava/util/List;":
  144. return new ArrayListObject(vm, Collections.<DvmObject<?>>emptyList());
  145. case "java/util/Enumeration->nextElement()Ljava/lang/Object;":
  146. return ((Enumeration) dvmObject).nextElement();
  147. case "java/util/Locale->getLanguage()Ljava/lang/String;":
  148. Locale locale = (Locale) dvmObject.getValue();
  149. return new StringObject(vm, locale.getLanguage());
  150. case "java/util/Locale->getCountry()Ljava/lang/String;":
  151. locale = (Locale) dvmObject.getValue();
  152. return new StringObject(vm, locale.getCountry());
  153. case "android/os/IServiceManager->getService(Ljava/lang/String;)Landroid/os/IBinder;": {
  154. ServiceManager serviceManager = (ServiceManager) dvmObject;
  155. StringObject serviceName = vaList.getObjectArg(0);
  156. assert serviceName != null;
  157. return serviceManager.getService(vm, serviceName.getValue());
  158. }
  159. case "java/io/File->getAbsolutePath()Ljava/lang/String;":
  160. File file = (File) dvmObject.getValue();
  161. return new StringObject(vm, file.getAbsolutePath());
  162. case "android/app/Application->getPackageManager()Landroid/content/pm/PackageManager;":
  163. case "android/content/ContextWrapper->getPackageManager()Landroid/content/pm/PackageManager;":
  164. case "android/content/Context->getPackageManager()Landroid/content/pm/PackageManager;":
  165. DvmClass clazz = vm.resolveClass("android/content/pm/PackageManager");
  166. return clazz.newObject(signature);
  167. case "android/content/pm/PackageManager->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;": {
  168. StringObject packageName = vaList.getObjectArg(0);
  169. assert packageName != null;
  170. int flags = vaList.getIntArg(1);
  171. if (log.isDebugEnabled()) {
  172. log.debug("getPackageInfo packageName=" + packageName.getValue() + ", flags=0x" + Integer.toHexString(flags));
  173. }
  174. return new PackageInfo(vm, packageName.getValue(), flags);
  175. }
  176. case "android/app/Application->getPackageName()Ljava/lang/String;":
  177. case "android/content/ContextWrapper->getPackageName()Ljava/lang/String;":
  178. case "android/content/Context->getPackageName()Ljava/lang/String;": {
  179. String packageName = vm.getPackageName();
  180. if (packageName != null) {
  181. return new StringObject(vm, packageName);
  182. }
  183. break;
  184. }
  185. case "android/content/pm/Signature->toByteArray()[B":
  186. if (dvmObject instanceof Signature) {
  187. Signature sig = (Signature) dvmObject;
  188. return new ByteArray(vm, sig.toByteArray());
  189. }
  190. break;
  191. case "android/content/pm/Signature->toCharsString()Ljava/lang/String;":
  192. if (dvmObject instanceof Signature) {
  193. Signature sig = (Signature) dvmObject;
  194. return new StringObject(vm, sig.toCharsString());
  195. }
  196. break;
  197. case "java/lang/String->getBytes()[B": {
  198. String str = (String) dvmObject.getValue();
  199. return new ByteArray(vm, str.getBytes());
  200. }
  201. case "java/lang/String->getBytes(Ljava/lang/String;)[B":
  202. String str = (String) dvmObject.getValue();
  203. StringObject charsetName = vaList.getObjectArg(0);
  204. assert charsetName != null;
  205. try {
  206. return new ByteArray(vm, str.getBytes(charsetName.getValue()));
  207. } catch (UnsupportedEncodingException e) {
  208. throw new IllegalStateException(e);
  209. }
  210. case "java/lang/Integer->toString()Ljava/lang/String;":{
  211. Integer iUse = (Integer)dvmObject.getValue();
  212. return new StringObject(vm, Integer.toString(iUse));
  213. }
  214. case "java/lang/StringBuffer->toString()Ljava/lang/String;":{
  215. StringBuffer str1 = (StringBuffer) dvmObject.getValue();
  216. return new StringObject(vm,str1.toString());
  217. }
  218. case "java/lang/StringBuffer->append(Ljava/lang/String;)Ljava/lang/StringBuffer;": {
  219. StringBuffer str1 = (StringBuffer) dvmObject.getValue();
  220. StringObject serviceName = vaList.getObjectArg(0);
  221. assert serviceName != null;
  222. return vm.resolveClass("java/lang/StringBuffer").newObject(str1.append(serviceName.getValue()));
  223. }
  224. case "java/security/cert/CertificateFactory->generateCertificate(Ljava/io/InputStream;)Ljava/security/cert/Certificate;":
  225. CertificateFactory factory = (CertificateFactory) dvmObject.getValue();
  226. DvmObject<?> stream = vaList.getObjectArg(0);
  227. assert stream != null;
  228. InputStream inputStream = (InputStream) stream.getValue();
  229. try {
  230. return vm.resolveClass("java/security/cert/Certificate").newObject(factory.generateCertificate(inputStream));
  231. } catch (CertificateException e) {
  232. throw new IllegalStateException(e);
  233. }
  234. case "java/security/cert/Certificate->getEncoded()[B": {
  235. Certificate certificate = (Certificate) dvmObject.getValue();
  236. try {
  237. return new ByteArray(vm, certificate.getEncoded());
  238. } catch (CertificateEncodingException e) {
  239. throw new IllegalStateException(e);
  240. }
  241. }
  242. case "java/security/MessageDigest->digest([B)[B": {
  243. MessageDigest messageDigest = (MessageDigest) dvmObject.getValue();
  244. ByteArray array = vaList.getObjectArg(0);
  245. assert array != null;
  246. return new ByteArray(vm, messageDigest.digest(array.getValue()));
  247. }
  248. case "java/util/ArrayList->remove(I)Ljava/lang/Object;": {
  249. int index = vaList.getIntArg(0);
  250. ArrayListObject list = (ArrayListObject) dvmObject;
  251. return list.getValue().remove(index);
  252. }
  253. case "java/util/List->get(I)Ljava/lang/Object;":
  254. List<?> list = (List<?>) dvmObject.getValue();
  255. return (DvmObject<?>) list.get(vaList.getIntArg(0));
  256. case "java/util/Map->entrySet()Ljava/util/Set;":
  257. Map<?, ?> map = (Map<?, ?>) dvmObject.getValue();
  258. return vm.resolveClass("java/util/Set").newObject(map.entrySet());
  259. case "java/util/Set->iterator()Ljava/util/Iterator;":
  260. Set<?> set = (Set<?>) dvmObject.getValue();
  261. return vm.resolveClass("java/util/Iterator").newObject(set.iterator());
  262. }
  263. throw new UnsupportedOperationException(signature);
  264. }
  265. }

三、打包成jar,方便其它程序调用

IDEA 找到 File → Project Structure …​ 然后选择 Artifacts, 点加号 Add 
如图配置,勾上 Include tests

点击ok后
Build → Build Artifacts进行编译
编译成功后会生成很多jar文件

在控制台测试运行下
 java -jar unidbg-master.jar

运行出了结果,证明打包的没问题

四、进行python调用打包的jar包

  1. # coding:utf-8
  2. import requests, urllib, subprocess
  3. import chardet, jpype,os
  4. headers = {
  5. "Host": "api.m.jd.com",
  6. "charset": "UTF-8",
  7. "cache-control": "no-cache",
  8. "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
  9. "user-agent": "okhttp/3.12.1"
  10. }
  11. cookies = {
  12. }
  13. url = "https://api.m.jd.com/client.action"
  14. params = {
  15. "functionId": "wareBusiness",
  16. "clientVersion": "9.2.2",
  17. "build": "85371",
  18. "client": "android",
  19. "d_brand": "360",
  20. "d_model": "1605-A01",
  21. "osVersion": "6.0.1",
  22. "screen": "1920*1080",
  23. "partner": "ks012",
  24. "aid": "xxx",
  25. "oaid": "",
  26. "eid": "xxx",
  27. "sdkVersion": "23",
  28. "lang": "zh_CN",
  29. "uuid": "xxx",
  30. "area": "24_2144_2149_21104",
  31. "networkType": "wifi",
  32. "wifiBssid": "xxx",
  33. # "st": "1665562015795",
  34. # "sign": "45a7dc3f547be113a6a4dfa942e190c6",
  35. # "sv": "111"
  36. }
  37. body = '''{"abTest800":true,"avoidLive":false,"brand":"360","cityId":2144,"darkModelEnum":3,"districtId":24463,"eventId":"Searchlist_Productid","fromType":0,"isDesCbc":true,"latitude":"","lego":true,"longitude":"","model":"1605-A01","ocrFlag":false,"pluginVersion":90220,"plusClickCount":0,"plusLandedFatigue":0,"provinceId":"24","skuId":"10024083045618","source_type":"search","source_value":"鼠标垫小号","townId":51707,"uAddrId":"0"}'''
  38. data = {
  39. "lmt": "0",
  40. "body": body,
  41. "": ""
  42. }
  43. jvmPath=jpype.getDefaultJVMPath()
  44. d='unidbg_master_jar2/unidbg-master.jar'#对应jar地址
  45. jpype.startJVM(jvmPath,"-ea","-Djava.class.path="+d+"")
  46. JDClass=jpype.JClass("com.kdd.test.runliudq") //类目
  47. jd=JDClass()
  48. signature=jd.runJni(["wareBusiness", body, "uuid", "android", "9.2.2"])
  49. url = url + "?" + urllib.parse.urlencode(params) + "&" + str(signature)
  50. print(url)
  51. response = requests.post(url, headers=headers, cookies=cookies, data=data)
  52. print(response.text)
  53. print(response)
  54. jpype.shutdownJVM()

 成功跑出结果

总结

这个案例网上有很多,适合入门哈哈

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/158461
推荐阅读
相关标签
  

闽ICP备14008679号