




免费预览已结束,剩余14页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android逆向分析案例某地图的定位请求分析微信里面有个“附近的人”,相信大家都知道,大概的原理就是调用腾讯地图的sdk进行定位,然后把个人的定位信息发到微信服务器上进行处理,再把一定范围内的人的信息返回并用列表的形式显示出来。因为刚踏入逆向分析这行,所以抱着学习的态度,研究一下大公司的东西,涨一下知识,嗯,本次的案例就是分析腾讯地图中定位请求数据的加解密,以及搭建简易的APK模拟实现定位请求。为了分析这一案例,是要掌握一定的分析工具的,其中包括APKTOOL, Sublime-Text, Xposed框架,Wireshark等。嗯,作为分析笔记,我就不细说了,只是将分析的步骤一步步地列举出来。首先,下载微信APK,利用APKTOOL在DOS下敲命令生成smali文件夹,这个过程我就不说了,前面博客已介绍过APKTOOL的使用方法。对于初学者来说,他们喜欢看到直接明了的源代码,所以他们会喜欢用dex2jar去反编译,并利用jd-gui去查看代码,包括我当初也是如此,但现在我为什么不用dex2jar和jd-gui去分析呢?再往下看看然后用smali文件查看工具Sublime-Text 3打开其刚刚生成的smali文件夹,如下图:嗯,反编译出来的文件数量令人感到窒息的,是不是有点感到逆向分析的痛苦了?要在如此多的smali文件里找到对应的类,并定位到关键的代码,这是需要一定的技巧的,不然你就只能码海捞针了。顺便一提,这货混淆得太好了,里面的可读性非常差,而且通过smali可以看到代码是有一定的复杂性的,特别多goto语句,所以如果用jd-gui浏览代码的话,是很不准确的,而且有一些内部类jd-gui是不会显示出来的等等。总而言之,smali的表达基本是正确的,但jd-gui转变过程并没有那么智能,所以jd-gui所表达的信息很大程度是错的,只能辅助用,不能依赖。既然我们要找的是地图地位请求,那么肯定涉及到网络,那么又怎么能少了抓包过程呢?好,进入微信,打开wireshark,在点击“附近的人”按钮同时观察wireshark抓到的包,主要是Http协议的包。很好抓,如下图:接着,我们右键打开选项,并选择“追踪流”,查看Http请求数据的TCP流,并尝试去从请求中找到关键字符串:可以从抓到的包看到,在请求行和请求头中有我们想要的关键字符串,至于请求体就不用细看了,已被加密过,但我们的目的就是要分析其加解密原理。SO,接下来一步就是通过关键字符串,在码海中定位到关键的代码。先回到刚才用Sublime-Text打开smali文件夹的界面,在界面中找到ct包(包名已被混淆,实际就是集成地图sdk的jar包),在该包下的所有smali文件查找刚才抓包的关键字符串,这里只用了“/loc?c=1&mars=0&obs=1”中的“mars”进行查找。我们可以看到,在搜索结果里找到了该字符串在哪里被调用了,很好,就在br.smali这个文件中,那么我们找到br.smali文件,并打开它:然后,可以看到字符串是在br.smali中的a(II)方法中调用的,那么我们就继续顺藤摸瓜根据smali语法,构造搜索字符串“Lct/br;-a(II)”, 通过这个字符串,我们可以利用Find in Floder的搜索功能,知道在哪里调用了这个函数:不错,已经找到了核心文件bz.smali,我就先说了吧,该类有两个内部类一个bz$1,另一个bz$a(美元符号代表内部类),bz$1是一个继承了Runnable的一个线程类,bz$a就是一个封装数据的类,包括加密后的数据和请求地址。因为我们是要找到加解密的原理,所以在找关键代码的时候,要多留心带有String类,和byte数组参数的函数,这些往往就是我们的Targetso,不妨大致浏览一下bz.smali里涉及到String和byte的函数:看到红色圈出来的代码了吗,那就是关键代码了。我就先直接说了吧,1:String为数据明文 , 2. 3:明文.getBytes(gbk)得到byte, 4:b$a类的a方法,该方法就是利用Java中的DeflaterOutputStream压缩处理, 5:将压缩后的byte作为参数放到 bz类的a方法中处理,该方法内还调用了so库的本地方法进行异或加密,这个后面会说明, 6:初始化一个bz$a类,该类封装了加密后的数据byte和地址String。当初始化bz$a类后,它会被压进一个LinkedBlockingQueue队列中,即调用其offer方法;然后在bz$1线程类,再次take出来,将其byte get出来,作为Http请求体的数据。那么,有人就问,为什么你就确定一定会调用这个函数呢?Good Question,别看我说得那么轻松,实际在通过关键字符找关键代码的同时,有必要通过Xposed框架的hook技术来验证是否调用了这个函数,又或者hook这个函数,查看其参数和参数的变化等,这也是很重要的。Xposed框架使用前面博客有介绍,这里不费口水了。下面就是我通过Xposed框架中的一个模块,hook到这个函数的:从上图可以看到,我hook了bz的函数a,并获得其第一个参数String,并打印在Log中,可见确实是一段明文,这段明文是Json格式的,里面包含了各种信息,包括手机imei, imsi,mac, 以及基站和周边wifi的信息。这样一来,我们就可以确定这个函数确实是被调用了。明文getBytes(gbk)调用了压缩处理的函数, b$a-a(B)B (smali格式的调用),那么我们可以利用jd-gui打开b.smali文件,并查看其内部类a中的a方法(丫的,混淆得太恶心了,都是什么abcd什么鬼的),切记,不要依赖jd-gui,上面的信息只能作为大概参考:从红色圈住的代码看到,就是DeflaterOutputStream的压缩处理,该a方法的下面还有一个b方法,处理的原理反过来的,即用InflaterInputStream对http的返回数据进行解压缩处理:除了对数据进行解压缩处理外,还有一个异或加密,我们上面提到的步骤5:将压缩后的byte作为参数放到 bz类的a方法中处理,该方法内还调用了so库的本地方法进行异或加密,实际上可以通过顺藤摸瓜找到最终函数:调用了e类的 o方法,该方法是native方法,用一般的方法是看不了so库内的代码的,但IDA PRO貌似是可以看其汇编代码分析的,这个是有一定难度的。不过,这里我们可以假定它里面的处理只是一个简单的异或加密,那么我们就可以修改参数,将byte全部置0,通过异或运算找出其key。这是关键点,通过000000key=key。因为 e的o函数调用内嵌在bz的a(BI)方法里,所以我们只需要hook外面那层函数就可以了,注意,这里的bz有两个a方法,混淆得恶心,但参数是不一样的:我这里new了一个长度为100,值全为0的byte,key和0异或等于key本身,那么我们看看是否这个本地方法里的处理是不是异或?从Log中可以看到,before是0,after是8个字节为一循环体的字节数组,显然,这是个以 8个字节为key的异或加密,很好,看脸破解了就省事了,哈哈至此,整个数据从明文到密文就分析完成了,至于http返回后的数据实际上只需要解压操作就出明文了,不再需要异或处理一次,所以就不讲返回数据的处理了。接下来,数据处理完了,那么就分析是怎么发送请求的。还记得上面抓包的那个图不?可以在请求数据中看到请求头有关键字符串“Halley-sdk.”,通过这个字符串,在sublime text中“find in folder”,在文件夹内搜索到该关键字符串,然后顺藤摸瓜,后面你懂的,找到文件后,分析一下smali,大概就是用了apache接口的HttpClient进行一个请求而已。那么,到这里,我们需要梳理一下,直接上流程图吧:好了,有了思路,那么就用java进行模拟吧,我是在eclipse上模拟的,当然,也可以在AndroidStudio上写个简单APK。eclipse中我用了两种Http请求,一种是HttpClient,地图sdk中用得方法,需要导入httpclient,httpcore, httpmine三个jar包,貌似还需要有个logging的jar包,都需要到Apache的官网下载;第二种是HttpURLConnection,这个java本身提供,虽然实现起来稍麻烦,但还是可以的。之所以要用第二种方法,是因为Android Studio把第一种方法中的四个包都导进去的时候由于工具本身bug会导致打包不成功,生成不了APK,很郁闷下面把代码贴出来:微信里面有个“附近的人”,相信大家都知道,大概的原理就是调用腾讯地图的sdk进行定位,然后把个人的定位信息发到微信服务器上进行处理,再把一定范围内的人的信息返回并用列表的形式显示出来。因为刚踏入逆向分析这行,所以抱着学习的态度,研究一下大公司的东西,涨一下知识,嗯,本次的案例就是分析腾讯地图中定位请求数据的加解密,以及搭建简易的APK模拟实现定位请求。为了分析这一案例,是要掌握一定的分析工具的,其中包括APKTOOL, Sublime-Text, Xposed框架,Wireshark等。嗯,作为分析笔记,我就不细说了,只是将分析的步骤一步步地列举出来。首先,下载微信APK,利用APKTOOL在DOS下敲命令生成smali文件夹,这个过程我就不说了,前面博客已介绍过APKTOOL的使用方法。对于初学者来说,他们喜欢看到直接明了的源代码,所以他们会喜欢用dex2jar去反编译,并利用jd-gui去查看代码,包括我当初也是如此,但现在我为什么不用dex2jar和jd-gui去分析呢?再往下看看然后用smali文件查看工具Sublime-Text 3打开其刚刚生成的smali文件夹,如下图:嗯,反编译出来的文件数量令人感到窒息的,是不是有点感到逆向分析的痛苦了?要在如此多的smali文件里找到对应的类,并定位到关键的代码,这是需要一定的技巧的,不然你就只能码海捞针了。顺便一提,这货混淆得太好了,里面的可读性非常差,而且通过smali可以看到代码是有一定的复杂性的,特别多goto语句,所以如果用jd-gui浏览代码的话,是很不准确的,而且有一些内部类jd-gui是不会显示出来的等等。总而言之,smali的表达基本是正确的,但jd-gui转变过程并没有那么智能,所以jd-gui所表达的信息很大程度是错的,只能辅助用,不能依赖。既然我们要找的是地图地位请求,那么肯定涉及到网络,那么又怎么能少了抓包过程呢?好,进入微信,打开wireshark,在点击“附近的人”按钮同时观察wireshark抓到的包,主要是Http协议的包。很好抓,如下图:接着,我们右键打开选项,并选择“追踪流”,查看Http请求数据的TCP流,并尝试去从请求中找到关键字符串:可以从抓到的包看到,在请求行和请求头中有我们想要的关键字符串,至于请求体就不用细看了,已被加密过,但我们的目的就是要分析其加解密原理。SO,接下来一步就是通过关键字符串,在码海中定位到关键的代码。先回到刚才用Sublime-Text打开smali文件夹的界面,在界面中找到ct包(包名已被混淆,实际就是集成地图sdk的jar包),在该包下的所有smali文件查找刚才抓包的关键字符串,这里只用了“/loc?c=1&mars=0&obs=1”中的“mars”进行查找。我们可以看到,在搜索结果里找到了该字符串在哪里被调用了,很好,就在br.smali这个文件中,那么我们找到br.smali文件,并打开它:然后,可以看到字符串是在br.smali中的a(II)方法中调用的,那么我们就继续顺藤摸瓜根据smali语法,构造搜索字符串“Lct/br;-a(II)”, 通过这个字符串,我们可以利用Find in Floder的搜索功能,知道在哪里调用了这个函数:不错,已经找到了核心文件bz.smali,我就先说了吧,该类有两个内部类一个bz$1,另一个bz$a(美元符号代表内部类),bz$1是一个继承了Runnable的一个线程类,bz$a就是一个封装数据的类,包括加密后的数据和请求地址。因为我们是要找到加解密的原理,所以在找关键代码的时候,要多留心带有String类,和byte数组参数的函数,这些往往就是我们的Targetso,不妨大致浏览一下bz.smali里涉及到String和byte的函数:看到红色圈出来的代码了吗,那就是关键代码了。我就先直接说了吧,1:String为数据明文 , 2. 3:明文.getBytes(gbk)得到byte, 4:b$a类的a方法,该方法就是利用Java中的DeflaterOutputStream压缩处理, 5:将压缩后的byte作为参数放到 bz类的a方法中处理,该方法内还调用了so库的本地方法进行异或加密,这个后面会说明, 6:初始化一个bz$a类,该类封装了加密后的数据byte和地址String。当初始化bz$a类后,它会被压进一个LinkedBlockingQueue队列中,即调用其offer方法;然后在bz$1线程类,再次take出来,将其byte get出来,作为Http请求体的数据。那么,有人就问,为什么你就确定一定会调用这个函数呢?Good Question,别看我说得那么轻松,实际在通过关键字符找关键代码的同时,有必要通过Xposed框架的hook技术来验证是否调用了这个函数,又或者hook这个函数,查看其参数和参数的变化等,这也是很重要的。Xposed框架使用前面博客有介绍,这里不费口水了。下面就是我通过Xposed框架中的一个模块,hook到这个函数的:从上图可以看到,我hook了bz的函数a,并获得其第一个参数String,并打印在Log中,可见确实是一段明文,这段明文是Json格式的,里面包含了各种信息,包括手机imei, imsi,mac, 以及基站和周边wifi的信息。这样一来,我们就可以确定这个函数确实是被调用了。明文getBytes(gbk)调用了压缩处理的函数, b$a-a(B)B (smali格式的调用),那么我们可以利用jd-gui打开b.smali文件,并查看其内部类a中的a方法(丫的,混淆得太恶心了,都是什么abcd什么鬼的),切记,不要依赖jd-gui,上面的信息只能作为大概参考:从红色圈住的代码看到,就是DeflaterOutputStream的压缩处理,该a方法的下面还有一个b方法,处理的原理反过来的,即用InflaterInputStream对http的返回数据进行解压缩处理:除了对数据进行解压缩处理外,还有一个异或加密,我们上面提到的步骤5:将压缩后的byte作为参数放到 bz类的a方法中处理,该方法内还调用了so库的本地方法进行异或加密,实际上可以通过顺藤摸瓜找到最终函数:调用了e类的 o方法,该方法是native方法,用一般的方法是看不了so库内的代码的,但IDA PRO貌似是可以看其汇编代码分析的,这个是有一定难度的。不过,这里我们可以假定它里面的处理只是一个简单的异或加密,那么我们就可以修改参数,将byte全部置0,通过异或运算找出其key。这是关键点,通过000000key=key。因为 e的o函数调用内嵌在bz的a(BI)方法里,所以我们只需要hook外面那层函数就可以了,注意,这里的bz有两个a方法,混淆得恶心,但参数是不一样的:我这里new了一个长度为100,值全为0的byte,key和0异或等于key本身,那么我们看看是否这个本地方法里的处理是不是异或?从Log中可以看到,before是0,after是8个字节为一循环体的字节数组,显然,这是个以 8个字节为key的异或加密,很好,看脸破解了就省事了,哈哈至此,整个数据从明文到密文就分析完成了,至于http返回后的数据实际上只需要解压操作就出明文了,不再需要异或处理一次,所以就不讲返回数据的处理了。接下来,数据处理完了,那么就分析是怎么发送请求的。还记得上面抓包的那个图不?可以在请求数据中看到请求头有关键字符串“Halley-sdk.”,通过这个字符串,在sublime text中“find in folder”,在文件夹内搜索到该关键字符串,然后顺藤摸瓜,后面你懂的,找到文件后,分析一下smali,大概就是用了apache接口的HttpClient进行一个请求而已。那么,到这里,我们需要梳理一下,直接上流程图吧:好了,有了思路,那么就用java进行模拟吧,我是在eclipse上模拟的,当然,也可以在Android Studio上写个简单APK。eclipse中我用了两种Http请求,一种是HttpClient,地图sdk中用得方法,需要导入httpclient,httpcore, httpmine三个jar包,貌似还需要有个logging的jar包,都需要到Apache的官网下载;第二种是HttpURLConnection,这个java本身提供,虽然实现起来稍麻烦,但还是可以的。之所以要用第二种方法,是因为Android Studio把第一种方法中的四个包都导进去的时候由于工具本身bug会导致打包不成功,生成不了APK,很郁闷下面把代码贴出来:java view plain copy 在CODE上查看代码片派生到我的代码片public class MainActivity extends Activity private Button btnRequest; private TextView tvRequest, tvResponse; Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvRequest=(TextView)findViewById(R.id.tv_request_data); tvResponse=(TextView)findViewById(R.id.tv_response_data); btnRequest=(Button)findViewById(R.id.btn_request); btnRequest.setOnClickListener(new View.OnClickListener() Override public void onClick(View v) tvRequest.setText(generateJsonObject().toString(); tvResponse.setText(); new Thread(new Runnable() Override public void run() try URL url=new URL(/loc?c=1&mars=0&obs=1); HttpURLConnection httpConn=(HttpURLConnection)url.openConnection(); httpConn.setDoOutput(true); httpConn.setDoInput(true); httpConn.setUseCaches(false); httpConn.setRequestMethod(POST); httpConn.setRequestProperty(Connection, Keep-Alive); DataOutputStream dos=new DataOutputStream(httpConn.getOutputStream(); dos.write(xorEncrypt(deflater(generateJsonObject().toString().getBytes(gbk); dos.flush(); dos.close(); int resultCode=httpConn.getResponseCode(); Log.d(zz, resultCode:+resultCode); if(resultCode=HttpURLConnection.HTTP_OK) Log.d(zz, http response ok+resultCode); final ByteArrayOutputStream baos=new ByteArrayOutputStream(); byte buffer=ew byte1024; InputStream is=httpConn.getInputStream(); int i=0; while(i=is.read(buffer)!=-1) baos.write(buffer, 0, i); tvResponse.post(new Runnable() Override public void run() try tvResponse.setText(new String(inflater(baos.toByteArray(), gbk); catch (Exception e) ); catch (Exception e) ).start(); ); /拼接一个明文JSONObect private JSONObject generateJsonObject() JSONObject dataJson=new JSONObject(); try dataJson.put(version, ); dataJson.put(address, 1); dataJson.put(source, 203); dataJson.put(access_token, 9d9e8211360ba90b8fbda2fcdbed21); dataJson.put(app_name, wechat); dataJson.put(app_label, 微信_6.3.18); dataJson.put(bearing, 1); dataJson.put(control, 2); dataJson.put(pstat, 5); dataJson.put(wlan, getWlanInfo(); dataJson.put(attribute, getAttributeInfo(); dataJson.put(location, new JSONObject(); dataJson.put(cells, getCellsInfo(); dataJson.put(wifis, getWifisInfo(); catch (JSONException jsonException) return dataJson; private JSONObject getWlanInfo() WifiManager wifiManager=(WifiManager)getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo=wifiManager.getConnectionInfo(); int rssi=wifiInfo.getRssi(); String ssid=wifiInfo.getSSID(); String bssid=wifiInfo.getBSSID(); JSONObject wlanJson=new JSONObject(); try wlanJson.put(mac, bssid); wlanJson.put(rssi, rssi); wlanJson.put(ssid, ssid); catch (JSONException e) return wlanJson; private JSONObject getAttributeInfo() WifiManager wifiManager=(WifiManager)getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo=wifiManager.getConnectionInfo(); String mac=wifiInfo.getMacAddress().replace(:, ); TelephonyManager telephonyManager=(TelephonyManager)getSystemService(TELEPHONY_SERVICE); String imei=telephonyManager.getDeviceId(); String imsi=telephonyManager.getSubscriberId(); JSONObject attributeJson=new JSONObject(); try attributeJson.put(mac, mac); attributeJson.put(imsi, imsi); attributeJson.put(imei, imei); attributeJson.put(qq, ); attributeJson.put(phonenum, ); catch (JSONException e) return attributeJson; private JSONArray getCellsInfo() TelephonyManager telephonyManager=(TelephonyManager)getSystemService(TELEPHONY_SERVICE); JSONArray jsonArray=new JSONArray(); JSONObject cellJson=new JSONObject(); try cellJson.put(mcc, 460); cellJson.put(mnc, 0); cellJson.put(lac, 42360); cellJson.put(cellid, 45370604); cellJson.put(rss, -88); cellJson.put(seed, 1); catch (JSONException e) jsonArray.put(cellJson); return jsonArray; private JSONArray getWifisInfo() JSONArray jsonArray=new JSONArray(); WifiManager wifiManager=(WifiManager)getSystemService(Context.WIFI_SERVICE); wifiManager.startScan(); List wifis=wifiManager.getScanResults()
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 碳捕集利用技术集成与应用方案
- 2025年新能源汽车自动驾驶技术保险理赔服务创新与市场拓展报告
- 环境咨询方案难写不
- 咨询主动获客方案
- 屿你婚礼活动策划方案
- 中药配方颗粒市场国际化战略布局:2025年质量标准与竞争策略分析
- 2025年格林童话测试题及答案
- DB65T 4384-2021 向日葵列当综合防治技术规程
- DB65T 4368-2021 土壤 石油类的测定 荧光光度法
- 断电后应急预案(3篇)
- 《中国美术简史》课件
- 意义未明的单克隆免疫球蛋白病病因介绍
- 大客户销售工作规划及思路
- 【MOOC】当代社会中的科学与技术-南京大学 中国大学慕课MOOC答案
- 学习六条禁令心得体会
- 京东方校园2024招聘胜任力测评题库
- 中建营盘山隧道2号斜井泄水专项施工方案
- CAD教程-AutoCAD2024全套教程
- 纺织品印花质量检测
- 《直播电商》课程标准
- 机房动力环境监控系统调试自检报告
评论
0/150
提交评论