当前位置: 首页 > news >正文

服务器做网站流程手机网站开发者模式

服务器做网站流程,手机网站开发者模式,租域名和服务器要多少钱,网站管理页面前言 在逆向过程中#xff0c;需要结合frida或unidbg#xff0c;对整个算法进行一步步的分析#xff0c;有时候我们分析完某一部分#xff0c;想要继续往下分析时#xff0c;需要重新发起请求#xff0c;这时候的参数往往都已经改变了#xff0c;这样会打断我们的节奏需要结合frida或unidbg对整个算法进行一步步的分析有时候我们分析完某一部分想要继续往下分析时需要重新发起请求这时候的参数往往都已经改变了这样会打断我们的节奏影响效率。此外有些算法除了我们外部传进去的参数外还有一些其他的参数参与了加密比如时间戳随机数一旦这些参与了算法那么即使每次的传入参数不变加密的结果还是会变。 外部输入参数的固定 frida 在京东app的hook中我们选择编写一个函数能够固定的调用Java层的native函数。 var bptr Module.findBaseAddress(libjdbitmapkit.so) console.log(bptr);function hook_12ECC() {Interceptor.attach(bptr.add(0x12ECC1), {onEnter: function(args) {this.arg0 args[0];this.arg3 args[3];console.log(args[0], args[1], args[2], args[3], args[4]);dump(arg0-ptr0, args[0].readPointer());dump(arg0-ptr1, args[0]);dump(arg0-ptr1, args[0].add(4).readPointer(), 64);console.log(arg1, args[1].readCString());// dump(arg2, args[2]);console.log(arg3, args[3].readCString(parseInt(args[4])));},onLeave: function(){console.log(arg0-ret, this.arg0);dump(ret-arg0-ptr1, this.arg0);// dump(ret-arg0-ptr2, this.arg0.add(8).readPointer());dump(12ecc-ret-arg2, this.arg3)}}) }function callBitmapkitUtils() {var BitmapkitUtils Java.use(com.jingdong.common.utils.BitmapkitUtils);var currentApplication Java.use(android.app.ActivityThread).currentApplication();var context currentApplication.getApplicationContext();var b clientImage;var c {moduleParams:{18:1565611060638,19:1565229712150,25:1567478504636,27:1602488415048,28:1631069159956,30:1567404005627,32:1567997588476,34:1593508185597,35:1568708316462,37:1630293538664,42:1623741761542,44:1569247647090,46:1588839806224,47:1571295610042,61:1582091758495,70:1585279774645,74:1586781606615}};var d d5a585639f505b18;var e android;var f 10.2.0;var res BitmapkitUtils.getSignFromJni(context, b, c, d, e, f);console.log(res: , res); }Java.perform(function() {hook_12ECC(); })然后启动frida之后可以在shell中输入callBitmapkitUtils()来调用函数。 这样一来不像在手机上滑动页面、点击页面那样有时会有多个请求发出会多次调用加密的方法。这样的好处是再也不用在手机上操作了而且请求的内容和个数是可控的。不过我们注意到京东的参数里有st和sv这两个参数这可不是由我们传入的属于内部输入参数接下来我们要固定它们。 unidbg 对于unidbg而言在我们编写代码的时候一般都是固定输入的 内部输入参数的固定 frida 对于内部输入参数而言可能有时间戳随机数常量数字或字符其中前2个是会改变的这会影响逆向分析所以需要固定这两个参数。时间戳一般是调用libc.so的gettimeofday函数随机数则是调用libc.so的lrand48或srand48 function hook_libc(){var ptr_t Module.findExportByName(libc.so, gettimeofday);Interceptor.attach(ptr_t, {onEnter: function(args){this.arg0 args[0];},onLeave: function() {this.arg0.writeU32(1639393559);this.arg0.add(4).writeU32(0);}});Interceptor.attach(Module.findExportByName(libc.so , lrand48), {onEnter: function(args) {},onLeave:function(retval){retval.replace(1);}}); } Java.perform(function() {hook_libc();hook_12ECC(); })这样一来即使多次运行st和sv也不会改变有利于我们的分析。 不过固定时间戳有个问题其他函数在获取时间戳的时候发现不对可能会导致frida环境崩溃所以我们希望只在调用的时候固定时间戳。所以我们更新如下代码 var logvar 0;function callBitmapkitUtils() {var BitmapkitUtils Java.use(com.jingdong.common.utils.BitmapkitUtils);var currentApplication Java.use(android.app.ActivityThread).currentApplication();var context currentApplication.getApplicationContext();var b clientImage;var c {moduleParams:{18:1565611060638,19:1565229712150,25:1567478504636,27:1602488415048,28:1631069159956,30:1567404005627,32:1567997588476,34:1593508185597,35:1568708316462,37:1630293538664,42:1623741761542,44:1569247647090,46:1588839806224,47:1571295610042,61:1582091758495,70:1585279774645,74:1586781606615}};var d d5a585639f505b18;var e android;var f 10.2.0;logvar 1;var res BitmapkitUtils.getSignFromJni(context, b, c, d, e, f);logvar 0;console.log(res: , res); }function hook_libc(){var ptr_t Module.findExportByName(libc.so, gettimeofday);Interceptor.attach(ptr_t, {onEnter: function(args){this.arg0 args[0];},onLeave: function() {if (logvar) {this.arg0.writeU32(1639393559);this.arg0.add(4).writeU32(0);}}});Interceptor.attach(Module.findExportByName(libc.so , lrand48), {onEnter: function(args) {},onLeave:function(retval){if (logvar){retval.replace(1);}}}); }这样一来只有在logvar值为1时才会固定参数。而logvar的默认值为0只有在调用callBitmapkitUtils方法的时候才会改为1调用完成后又会改为0。 unidbg 对于unidbg我们运行多次后会发现时间戳st会变sv一直是111好像和frida上的表现不一样难道出了什么问题 其实如果研究了京东libjdbitmapkit.so就会发现sv的后两位都是随机数余3。 而在unidbg对libc.so的随机数生成的实现中种子是固定的我猜的没深究源码导致生成的随机数的顺序是固定的继而导致余数是固定的。 public void hook_libc() {IHookZz hookZz HookZz.getInstance(emulator);hookZz.wrap(module.findSymbolByName(lrand48), new WrapCallbackHookZzArm32RegisterContext() {Overridepublic void preCall(Emulator? emulator, HookZzArm32RegisterContext ctx, HookEntryInfo info) {}Overridepublic void postCall(Emulator? emulator, HookZzArm32RegisterContext ctx, HookEntryInfo info) {int old ctx.getIntArg(0);System.out.println(Origin rand: old);ctx.setR0(1);}});hookZz.wrap(module.findSymbolByName(gettimeofday), new WrapCallbackHookZzArm32RegisterContext() {Overridepublic void preCall(Emulator? emulator, HookZzArm32RegisterContext ctx, HookEntryInfo info) {Pointer pointer ctx.getR0Pointer();ctx.push(pointer);}Overridepublic void postCall(Emulator? emulator, HookZzArm32RegisterContext ctx, HookEntryInfo info) {Pointer pointer ctx.pop();pointer.setLong(0, 1639388888);pointer.setLong(4, 0);}}); } public static void main(String[] args) {JingDong test new JingDong();test.hook_libc();test.callSign(); }可以看到时间戳已经被固定下来了而打印出来的两个随机数他们的除以3的余数都为1这也说明了为什么固定参数之前sv的值一直是111。 unidbg完整代码 package com.jingdong;import com.github.unidbg.AndroidEmulator; import com.github.unidbg.Emulator; import com.github.unidbg.Module; import com.github.unidbg.hook.hookzz.*; 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.array.ByteArray; import com.github.unidbg.linux.android.dvm.jni.ProxyDvmObject; import com.github.unidbg.linux.android.dvm.wrapper.DvmInteger; import com.github.unidbg.memory.Memory; import com.sun.jna.Pointer; import sun.security.pkcs.PKCS7; import sun.security.pkcs.ParsingException;import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.ObjectOutputStream; import java.security.cert.X509Certificate;public class JingDong extends AbstractJni {private final AndroidEmulator emulator;private final VM vm;private final Module module;public static String pkgName com.jingdong.app.mall;public static String apkPath unidbg-android/src/test/java/com/jingdong/jingdong9.2.2.apk;public static String soPath unidbg-android/src/test/java/com/jingdong/libjdbitmapkit.so;private static final String APK_PATH /data/app/com.jingdong.app.mall.apk;JingDong() {emulator AndroidEmulatorBuilder.for32Bit().setProcessName(pkgName).build();final Memory memory emulator.getMemory();memory.setLibraryResolver(new AndroidResolver(23));vm emulator.createDalvikVM(new File(apkPath));DalvikModule dm vm.loadLibrary(new File(soPath), false);vm.setJni(this);vm.setVerbose(true);dm.callJNI_OnLoad(emulator);module dm.getModule();}Overridepublic DvmObject? getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {switch (signature) {case com/jingdong/common/utils/BitmapkitUtils-a:Landroid/app/Application;: {return vm.resolveClass(android/app/Activity, vm.resolveClass(android/content/ContextWrapper, vm.resolveClass(android/content/Context))).newObject(null);}}return super.getStaticObjectField(vm, dvmClass, signature);}Overridepublic DvmObject? getObjectField(BaseVM vm, DvmObject? dvmObject, String signature) {switch (signature) {case android/content/pm/ApplicationInfo-sourceDir:Ljava/lang/String;: {return new StringObject(vm, APK_PATH);}}return super.getObjectField(vm, dvmObject, signature);}Overridepublic DvmObject? callStaticObjectMethod(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {switch (signature) {case com/jingdong/common/utils/BitmapkitZip-unZip(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)[B: {StringObject apkPath varArg.getObjectArg(0);StringObject directory varArg.getObjectArg(1);StringObject filename varArg.getObjectArg(2);if (APK_PATH.equals(apkPath.getValue()) META-INF/.equals(directory.getValue()) .RSA.equals(filename.getValue())) {byte[] data vm.unzip(META-INF/JINGDONG.RSA);return new ByteArray(vm, data);}}case com/jingdong/common/utils/BitmapkitZip-objectToBytes(Ljava/lang/Object;)[B: {DvmObject? obj varArg.getObjectArg(0);byte[] bytes objectToBytes(obj.getValue());return new ByteArray(vm, bytes);}}return super.callStaticObjectMethod(vm ,dvmClass, signature, varArg);}Overridepublic DvmObject? newObject(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {switch (signature) {case sun/security/pkcs/PKCS7-init([B)V: {ByteArray array varArg.getObjectArg(0);try {return vm.resolveClass(sun/security/pkcs/PKCS7).newObject(new PKCS7(array.getValue()));} catch (ParsingException e) {throw new IllegalStateException(e);}}}return super.newObject(vm, dvmClass, signature, varArg);}Overridepublic DvmObject? callObjectMethod(BaseVM vm, DvmObject? dvmObject, String signature, VarArg varArg) {switch (signature) {case sun/security/pkcs/PKCS7-getCertificates()[Ljava/security/cert/X509Certificate;: {PKCS7 pkcs7 (PKCS7) dvmObject.getValue();X509Certificate[] certificates pkcs7.getCertificates();return ProxyDvmObject.createObject(vm, certificates);}}return super.callObjectMethod(vm, dvmObject, signature, varArg);}Overridepublic DvmObject? newObjectV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {switch (signature) {case java/lang/StringBuffer-init()V: {return vm.resolveClass(java/lang/StringBuffer).newObject(new StringBuffer());}case java/lang/Integer-init(I)V: {return DvmInteger.valueOf(vm, vaList.getIntArg(0));}}return super.newObjectV(vm, dvmClass, signature, vaList);}Overridepublic DvmObject? callObjectMethodV(BaseVM vm, DvmObject? dvmObject, String signature, VaList vaList) {switch (signature) {case java/lang/StringBuffer-append(Ljava/lang/String;)Ljava/lang/StringBuffer;: {StringBuffer buffer (StringBuffer) dvmObject.getValue();StringObject str vaList.getObjectArg(0);buffer.append(str.getValue());return dvmObject;}case java/lang/Integer-toString()Ljava/lang/String;: {return new StringObject(vm, ((Integer)dvmObject.getValue()).toString());}case java/lang/StringBuffer-toString()Ljava/lang/String;: {return new StringObject(vm, ((StringBuffer)dvmObject.getValue()).toString());}}return super.callObjectMethodV(vm, dvmObject, signature, vaList);}private static byte[] objectToBytes(Object obj) {try {ByteArrayOutputStream baos new ByteArrayOutputStream();ObjectOutputStream oos new ObjectOutputStream(baos);oos.writeObject(obj);oos.flush();byte[] array baos.toByteArray();oos.close();baos.close();return array;} catch (IOException e) {throw new IllegalStateException(e);}}public void hook_libc() {IHookZz hookZz HookZz.getInstance(emulator);hookZz.wrap(module.findSymbolByName(lrand48), new WrapCallbackHookZzArm32RegisterContext() {Overridepublic void preCall(Emulator? emulator, HookZzArm32RegisterContext ctx, HookEntryInfo info) {}Overridepublic void postCall(Emulator? emulator, HookZzArm32RegisterContext ctx, HookEntryInfo info) {int old ctx.getIntArg(0);System.out.println(Origin rand: old);ctx.setR0(1);}});hookZz.wrap(module.findSymbolByName(gettimeofday), new WrapCallbackHookZzArm32RegisterContext() {Overridepublic void preCall(Emulator? emulator, HookZzArm32RegisterContext ctx, HookEntryInfo info) {Pointer pointer ctx.getR0Pointer();ctx.push(pointer);}Overridepublic void postCall(Emulator? emulator, HookZzArm32RegisterContext ctx, HookEntryInfo info) {Pointer pointer ctx.pop();pointer.setLong(0, 1639388888);pointer.setLong(4, 0);}});}public void callSign() {DvmClass cBitmapkitUtils vm.resolveClass(com/jingdong/common/utils/BitmapkitUtils);StringObject ret cBitmapkitUtils.callStaticJniMethodObject(emulator, getSignFromJni()(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;,vm.resolveClass(android/content/Context).newObject(null),clientImage,{\moduleParams\:{\18\:\1565611060638\,\19\:\1565229712150\,\25\:\1567478504636\,\27\:\1602488415048\,\28\:\1631069159956\,\30\:\1567404005627\,\32\:\1567997588476\,\34\:\1593508185597\,\35\:\1568708316462\,\37\:\1630293538664\,\42\:\1623741761542\,\44\:\1569247647090\,\46\:\1588839806224\,\47\:\1571295610042\,\61\:\1582091758495\,\70\:\1585279774645\,\74\:\1586781606615\}},d5a585639f505b18,android,10.2.0);System.out.println(ret.getValue());}public static void main(String[] args) {JingDong test new JingDong();test.hook_libc();test.callSign();} }关于京东加密 其实京东app有3套加密方案会根据随机数不同来选择不同的方案而unidbg生成的随机数和京东cv的生成方案导致sv一直是固定的从而一直调用其中一套方案。我们在逆向的时候其实只需要逆向出其中一套方案即可那个简单选哪个如果刚好是调用的那套方案的话那还好。如果不是一时之间又不知道怎么处理的话就有点倒霉了。 我将这个解密方法封装成api了直接调用api可以解密很方便了 技术交流QQ 408737515
http://www.hkea.cn/news/14492230/

相关文章:

  • 网站建站与优化上海关键词排名优化价格
  • 在局域网服务器建设网站教程郑州定制开发小程序
  • 网站站建设建设中页中页设计公司前十名
  • 做图表的网站知乎国家高新技术企业认定官网
  • 相亲网站建设策划方案网站优化个人工作室
  • 网站模板 phpcms可以做pos机的网站
  • 百度网站诚信认证做视频背景音乐网站
  • 外贸开发网站公司seo交流论坛seo顾问
  • 一个网站网站建设下来要花多少钱公众号做视频网站吗
  • cms搭建网站山东省住房和城乡建设厅电话号码
  • 网站建设与营销保山网站建设报价
  • 阿里巴巴网站建设代理广西网站建设设计
  • 东阳网站建设方案汽车价格网
  • 做网站免费吗公众号文章制作
  • 网站设计的技巧盐城专业网站建设哪家好
  • 衡水做网站服务商一个可以看qq空间的网站
  • 怎么建立个人网站定制网站 多少钱
  • 网站如何做团购深圳建站模板公司
  • dede网站优化做dw网站图片怎么下载地址
  • 在线做爰视频网站高等院校网站建设方案
  • 画册做的比较好的网站网站备案在哪里查询
  • 网站例子大全IT男网站建设
  • 牡丹菏泽网站建设移动软件管理的应用场景
  • 不符合网站外链建设原则的是汽车汽配网站建设
  • 网站建设合同严瑾手机端网页设计软件
  • flash 网站 模板交通建设监理协会网站
  • 哪里有网站建设流程phpnow超详细WordPress
  • 有后台网站怎么做公司网站开发 建设
  • 天津市建设银行网站怎样制作自己的app
  • 宁波住房和城乡建设局网站网站界面宽