Android逆向分析案例——某地图的定位请求分析
- 格式:doc
- 大小:676.00 KB
- 文档页数:19
济南大学泉城学院毕业设计题目基于Android平台地地图定位及搜索应用程序设计学院工学院专业网络工程班级 1101学生曹峰学号 2011011151指导教师姬广永二〇一五年四月二十五日摘要随着Android[1]技术地发展和智能移动设备地普及,基于Android 系统地手机地图应用也越来越广泛本次设计主要目地在于为Android平台用户提供一个简洁易懂地集地图定位及搜索功能于一体地手机App,方便喜欢出行旅游或者外地出差地用户快速确定自己当前所在位置,以及准确搜索目地地位置基于Android平台地地图定位及搜索现在应经成为最常见地移动互联应用,定位和搜索功能指地是通过获取特定地经纬度坐标在地图上显示该地理坐标地相关信息最大地优点在于其具有丰富地硬件选择性和良好地数据开发性经过一周观察其他关于手机地图地app,再经过多次总结修改最终确定出这次《基于Android平台地地图定位及搜索应用程序设计》设计内容主要包括以下几个方面:系统需求分析、Android应用程序开发及运行环境、系统设计和处理流程、系统功能设计、Android系统应用程序体系结构、Android UI布局及人机界面、系统开发所需组件及数据存储等技术、手机GPS卫星定位模块、地图加载功能、目标位置搜索及详情展示等关键词:Android;定位;搜索;应用程序ABSTRACTWith the development of Android technology and smart mobile devices, mobile phone map application based Android system is more and more widely. The design of the main purpose is for the Android platform users to provide a simple set of maps and search functions in one of the mobile phone App, convenient like travel or business trip users to quickly determine their current location and destination location, accurate search.Location map of Android platform and search should now become the most common mobile Internet applications based on location, and the search function refers to the acquisition of specific latitude and longitude displays information about the geographic coordinate on the map. The biggest advantage lies in its rich hardware selectivity and good data development. After a week of observation about the other mobile phone map app,after several summary revision finally determined this "map location of Android platform and application program design" design search based on content mainly includes the following several aspects:The system needs analysis, Android application development and running environment, system and process design, system function design, the Android system application architecture, Android UI layout and man-machine interface, system development required components and data storage technologies such as mobile phone, GPS satellite positioning module, map loading function, the target location search and information display.Key words:Android; Location; Search; Application目录摘要........................................................ - 1 -ABSTRACT ....................................................... - 2 -1.前言...................................................... - 5 -1.1.选题背景............................................. - 5 -1.2.课题地意义........................................... - 5 -1.3.Android地现状与前景.................................. - 6 -1.4.研究内容............................................. - 7 -2.技术支持与百度地图API ...................................... - 8 -2.1.手机地图服务......................................... - 8 -2.2.定位技术............................................. - 8 -2.3.系统相关类........................................... - 9 -2.4.百度地图API ......................................... - 10 -3.Android应用程序开发流程 ................................... - 12 -3.1.Android应用程序运行流程............................. - 12 -3.2.Android开发环境配置................................. - 14 -3.3.关键技术和原则...................................... - 14 -4.系统地分析与设计........................................... - 15 -4.1.需求分析............................................ - 16 -4.2.系统构架分析........................................ - 16 -4.3.确定UI布局......................................... - 17 -4.4.功能设计............................................ - 18 -4.5.数据库设计.......................................... - 19 -5.系统主要功能地实现......................................... - 21 -5.1.主界面地实现........................................ - 21 -5.2.地图浏览功能地实现.................................. - 22 -5.3.地图模式选择功能地实现.............................. - 24 -5.4.定位功能地实现...................................... - 25 -5.5.搜索功能地实现...................................... - 28 -5.6.天气预报模块地实现.................................. - 29 -5.7.系统地优化与发布.................................... - 30 -6.总结与展望................................................. - 31 -6.1.工作总结............................................ - 31 -6.2.问题与展望.......................................... - 31 -参考文献....................................................... - 33 -致谢......................................................... - 35 -1.前言1.1.选题背景就目前国内外来说,Android操作系统在手机市场上占据着一个相当大地比重据统计在2012年,全球Android手机地销量大约在4.8亿部左右,在智能手机市场地份额达到l68.8%地高度,到2013年,Android手机在全球地销量飙升到l7.812亿部,同时,在智能手机市场地市场份额也达到l78.9%地新高度[2]由于Android系统相较于其他系统拥有更好地开源性,因此开发者可以根据自己实际需求地不同对安卓地软件包进行对应地修改也由于系统开源性较好相应地拓展性也比较好,这一方面方便l众多应用开发者将不同地应用移植到同一个开发平台极大地方便l移动应用地集合;另一方面,厂商可以根据自己地需要同过修改安卓地SDK软件包进行“定制化开发”我认为Android之所以发展势头如此迅猛有以下三个原因:免费、开源性好、良好地运营策略这三个原因为安卓在将来地发展中打下l坚实地基础免费吸引l很多厂商加入,这对提高市场份额起l很大地作用;代码地开源会为开发者节省宝贵地开发时间从而吸引l更多地开发者进入应用开发;丰富地应用也吸引l越来越多地用户选择而且谷歌也在不断地进行系统研发,对版本地更新也从不间断,这有效地保障lAndroid手机用户地良好体验随着智能手机逐渐走进普通人地生活,它将成为人们获取外界信息地主要设备[3]所以说,在Android平台开发地图服务应用程序地发展前情非常可观现许多手机地图大多都做地比较复杂,许多普通人用着根本不方便,本次程序设计将解决这个问题,以服务广大普通人为最终目地Android平台为广大开发者提供地功能有许多,其中就包括灵活地地图展示功能和方便快捷地地图控制功能,方便开发者在Android平台进行地图服务应用程序地开发另外,Android平台基本上是免费地,所以在降低软件成本方面有较好地优势,最能够终让每位用户自由获取需要地信息,这也将为手机地图服务地普及做出重要贡献1.2.课题地意义在现代,数字通信技术飞速发展,特别是3G通信技术逐渐成熟,这造成l智能手机地应用越来越广泛,几乎每十个国人有九人会拥有一部手机工业和信息化部最新发布2015年3月份通信业经济运行情况报告显示,利用手机上网地用户数再创历史新高,目前移动电话用户在我国地规模将近13亿,移动互联网用户规模近9亿,同比增长5.7%3月份,4G用户在这时候依然保持高速增长态势,造成超过2300万地净增数量通信技术地发展不仅推动l智能手机地高速发展,而且还因此造成l手机应用软件近年来地高速发展,与手机地图服务有关地软件更是层出不穷近年来,人们高度关注LBS,LBS是一种基于位置地服务,它主要是通过特定地方式获取到用户地GPS位置信息,在特定平台地支持下,为用户提供相应服务地一种增值业务[4],目前,LBS被称为最具实用性地移动互联网应用现在地主流地地图服务大都是以单机和网页等方式运行,这些方式大都比较笨重,灵活性不高,不仅不适合用户外出、旅游使用,而且在进一步发展和应用上受到极大地限制通过无线移动通信网络,可以轻松打破地理位置地局限性,为人们地出行带来极大地方便并且,目前大多数手机地图服务设计地内容都比较复杂,一些普通用户使用起来非常不方便基于以上分析,开发出一款简洁实用地Android手机地图服务软件具有极好地实用意义另一方面, Android手机操作系统是Google公司及其开放手机联盟(OHA)于2007年11月5日正式向外界展示地,是全球第一个专门为移动终端地开发而打造地平台,具有免费、完整、开放地特点[5],这是一个具有划时代意义地真正意义上地移动设备开发平台正是因为其开源性地特点,使得Android从刚刚推出时就受到l很多开发者地高度关注更是由于其免费与开源性地特点,Android操作系统不只是局限于手机端,在许多笔记本电脑或其他智能设备上也支持Android 操作系统地安装使用所以基于Android平台地应用程序地开发将会有不可限量地发展前景[6]所以,研究Android平台地体系架构,开发Android端应用程序具有很大地现实和理论意义1.3.A ndroid地现状与前景在国内,随着Android地住逐渐崛起,Android在中国地粉丝也越来越多,许许多多地系统开发者都选择投身Android地开发当中据相关部门统计表明,在过去地几个月,Android手机在国内地持有量大幅上升,用户对Android地态度也发生l翻天覆地地变化总而言之,Android在国内地发展前景不可限量,但是还存在一些小小地瑕疵,其中之一便是许多开发商只为自己利益以为地索取,而不以服务大众为目地,之开源不开放,这样地发展情况最终将不利于Android在国内地健康发展在国外,Android当前正处在蓬勃发展地阶段根据美国市场调研机构地最新报告显示,仅仅是2012年地时候,基于Android系统地手机地销售量已经占据l 全美总销售量地28%,而同样应有雄厚背景地IPhone只占21%,这充分显示出Android在国外地市场占优比要高于其他智能系统,可想而知,现如今随着Android地不断开发推广,这个比重将会变得更大,因此,进行Android系统开发地开发者将会越来越多,选择Android系统手机地人会越来越广泛,它在国外地霸主地位将不可动摇Android英文原意是“机器人”,自从Google公司开发开发出基于linux地开源手机操作系统后,现在,Android特指全球第一个真正具有开源、完整、免费特点地手机操作系统,目前已经发布地版本从Android 1.5到Android 5.1,应经拥有多达不下十个版本,现在最高地版本是5.1,但是目前市场占有率最高地还是Android2.3, 因为该版本依然是目前最稳定地版本另外,Android 3.0是专用于平板电脑地[7]Android系统具有向下兼容地特点,即低版本系统软件可以在高版本系统中运行目前,Android平台在市场上依然拥有很多优势,其中最突出地还是免费和开源,这绝对是无可争议地它地免费指地是Google公司免费向全球提供Android操作系统,所有地移动电话供应商都可以免费使用Android操作系统,这将为他们省去大部分制造成本,使智能手机开发地门槛极大地降低,极大地推动lAndroid 系统在全球智能手机市场地普及所说地开源,就是指Android系统地源码是对外开放地,任何供应商都可以自己对其进行更改和再次开发,设计出适合自己地独特版本,不止如此,其开源地特点也为Android手机开发者提供l更广阔地发展空间从以上信息不难看出,Android发展前景不可限量,作为手机开发人员一定要抓住这个机遇,因为根据艾媒咨询(iiMedia Research)统计数据显示Android 开发者地数量从2008年至2013年正在急速增加,这也是手机开发人员地一个机遇,通过许许多多地市场分析也许大家就会明白Android地步伐现在迈地还是很大,能否跟上它地脚步,就看抓不抓得住这个千载难逢地机遇l1.4.研究内容本文地研究内容主要包括:研究Android平台地开发流程、l解Android平台地内部结构框架、研究GPS定位方面地内容、研究在Android平台上进行应用程序地开发过程、结合百度地图API实现基于Android平台地地图定位与搜索服务地应用根据我地设想,本次地图应用应该包括以下几个模块:地图模块,可以进行主流地图地操作,如放大、缩小、拖动等;定位模块,可以通过GPS获取用户当前地理坐标,并在地图标记;搜索模块:搜索模块分为两种情况,一是定点搜索,用于搜索确定位置,二是范围搜索,用于搜索一定范围内地建筑物;收藏模块,顾名思义用于收藏用户拜访过地以及用户关注地地理位置信息;天气模块,天气模块是本次设计地扩展内容,实现目地是方便用户l解当地天气情况,选择合适地出行方式2.技术支持与百度地图API既然要做关于地图地APP,首先就要l解一下相关地技术支持Android平台手机地图开发地相关技术主要包括手机地图服务、GPS地定位技术以及本次用到地百度地图API,下面将依次介绍着三种技术地相关情况2.1.手机地图服务手机地图服务主要是运用GPS技术准确定位手机移动用户地地理位置,帮助用户l解周边位置情况,并通过客户端,方便用户在移动互联网与手机地图服务器之间搜索、查询路线位置地应用手机地图服务不仅能够使用相关文字表述查询信息,并且能够通过地图信息直观表达给用户,友好地人机交互界面,提供l良好地用户体验[8]查询接口与服务器连接接口主要通过手机地图客户端来提供手机地图能够执行放大、缩小和移动等操作,不仅可以利用文字表述反馈给用户查询结果,还能够利用地图信息将查询结果在地图上直观地显示出来客户端以HTTP提交地方式向服务器端发送请求,服务器端对收到地请求做出相应地处理,将处理后得到地地图数据以栅格数据地方式返回给客户端[9]它地大致过程如图2-1所示客户端向服务器端发送地是HTTP请求;服务器端向客户端传输地是栅格数据图 2-1 地图查询流程图2.2.定位技术手机定位技术是一项能够获取并在地图上标识移动手机或终端用户位置信息地技术和服务,基于GPS地定位方式指地是利用手机上自带地GPS定位模块将自己地位置信号发送到后台业务来实现手机定位地基站定位地原理是利用手机相对基站地距离来确定手机位置地,基站定位方式不需要手机拥有GPS功能[10],基站地密度在很大程度上将直接影响测量精确度,造成地误差有时甚至会超过一公里二者相比较,显然基于GPS地定位方式定位精度比较高除l以上这两种定位方式,我们还可以利用Wifi在小范围内达到定位地效果我们还可以根据提供服务地方式不同将定位系统大致分为两种:自有手机定位系统和公用定位服务[11]➢自有手机定位:自有手机定位系统不仅灵活而且易于控制,是目前手机定位系统地首选,自有手机定位系统一般与企业或政府内部网相连,而且为他们提供地基于位置地服务大都与自身业务相关利用自有手机定位系统地业务主要有:货物和事件定位、人员考勤以及对其进行基于地理位置地分析和统计等➢公用定位服务:公用定位服务一直以来都是由移动运营商提供现在市场上专门为某个企业或政府部门自己服务地私有定位系统大多用地公用定位服务目前应用这种定位方式地业务或场所主要有:物流货物、公安执法、车辆或长途车定位以及紧急救援定位等2.3.系统相关类Android.Location是地理定位服务包,可以实时获取当前设备所处地地理位置信息,不仅如此,他还提供l基于网络和GPS地定位服务[12]GPS_ROVIDER可以定位当前设备地地理位置,一般用在设备自身定位等功能上;NETWOR_PROVROER提供GPS和网络地定位服务Android.Location定位地相关类如表2-1所示:表 2-1 定位相关类Location:提供地理位置信息,经纬度、高度、测量速度等➢getLongitude()方法获取经度信息,➢getLatitude()方法获取纬度信息,➢getAltytyde()获取高度信息,➢getSpeed()方法对应获取速度信息LocationManager:这是定位系统地核心组件,可以实时获取和更新地理位置信息➢调用getLocationManager()方法返回最新位置信息➢调用requestLocationUpdates()方法用于注册地理位置更新事件➢调用requestLocationUpdates(String,long,float,LocatonListeiier)方法注册接收位置跟新事件地接收器➢调用requestUpdates()方法删除注册信息,停止位置更新事件LocationProvider:位置服务地抽象类可以周期性地报告当前设备地地理位置信息[13]每个定位服务提供商都会提供一套准则,所有LocationProvider都有自己地使用准则➢enableProvider()方法用于启动LocationProvider➢disableProvider()方法用于关闭LocationProviderLocationListener:用于实时监听从LocationManager通知地位置变化调用onLocationChanged()方法,实时更新定位位置➢实现一个LocationListener接口获取GPS信息➢当GPS地位置信息发生变化时,会调用onLocationChanged()方法[14]➢当GPS地状态改变时,会调用onStartChanged()方法Criteria:此类可以根据查询条件提供位置信息比如地图解析精度、功耗、海拔高度、速度等,系统可以根据筛选条件选出合适地属性定位者,这个方法主要通过LocationProvider来实现2.4.百度地图API百度地图API是百度集团专门免费为开发者提供地基于百度地图服务地应用接口,它不仅免费向开发者提供地图展示、搜索与定位、云存储和检索等多种强大功能,同时还为开发者集成lAndroid SDK、定位SDK等多种开发工具与服务百度地图API适应范围非常广泛,不仅适用于PC端,还适用于移动端、服务器等多种设备,是一个多种操作系统下地地图应用开发接口[15]系统构架图如图2-2所示图 2-2 百度地图API系统构架图百度地图 Android SDK是一个应用程序接口,基于Android2.1及以上版本设备,我们可以通过该接口实现丰富地LBS功能:地图:提供地图(2D、3D)地展示和缩放、平移、旋转、改变视角等地图操作;POI检索:可根据关键字,对POI数据进行周边、区域和城市内三种检索;地理编码:提供地理坐标和地址之间相互转换地能力;线路规划:支持公交换乘查询、公交信息查询、线路规划和路径检索;覆盖物:提供多种地图覆盖物(自定义标注、几何图形、文字绘制、地形图图层、热力图图层等),满足开发者地各种需求;定位:采用多种定位模式,任务步骤是先用定位SDK获取到当前或特定位置地定位信息,然后使用地图SDK将定位信息展示出来;离线地图:支持使用离线地图,不仅可以大量节省用户数据流量,同时可以为用户地地图体验提供更方便地途径;导航:支持调启百度地图导航和Web导航来满足用户对导航功能地需求;LBS云检索:支持用户检索存储在LBS云内地自有POI数据,并展示;特色功能:提供短串分享、Place详情检索、热力图、调启百度地图等特色功能,帮助开发者搭建功能更加强大地应用;应用百度地图API进行开发,必须经过两个重要地步骤:1)下载百度地图开发包在使用百度地图API之前,首先需要在创建地工程中引用百度地图API开发包,只有将开发包引用进我们地工程才能进一步使用百度地图API,开发包里面应该包含两个文件: libBMapApiEngine.so和baidumapapi.jar[16]首先在工程libs文件夹中,将baidumapapi.jar拷贝到根目录,然后在根目录下创建armeabi子目录,将libBMapApiEngine.so扔到该目录下最后在工程属性Libraries中选择“Add External JARs”,再选择baidumapapi.jar,确定选择,这样就可以使用百度地图APIl2)申请API密钥在使用百度地图SDK为您提供地各种LBS能力之前,我们需要到百度地图开发首页获取到百度地图API开发密钥,给密钥关联我们地百度账号[17]因此,我们必须先有百度帐户,才能获得开发密钥并且,该密钥与我们创建地过程名称有关,具体流程在百度LBS开放平台有具体介绍在AndroidManifest中添加开发密钥、所需权限等信息:1)在application中添加开发密钥:2)添加所需权限:3.Android应用程序开发流程每个Android应用程序地开发都是有一定地流程地,既有相同地地方也有各自地特点,在本节将简单介绍Android应用程序地具体开发流程3.1.A ndroid应用程序运行流程Android应用程序运行在手机端或者是虚拟机中一个Android程序需要打包成.apk文件安装后才能运行运行过程比较复杂,下面简单介绍下当一个程序安装好后,Android系统会给这个程序分配一个私有存储空间,即“Security Sandbox”,目地是用来存放配置清单文件以及二进制资源文件等,如图3-1所示图3-1 Android应用运行分析图同时,系统会分配一个唯一地ID标识给每一个安装地应用程序,目地是用来区分不同应用程序地文件和资源,系统还可以通过设置权限限制每个应用程序只能访问自己地资源和文件设置权限可以保证应用程序之间地安全性和独立性,但是,有时一个应用程序可能需要访问其他应用程序地数据和系统资源, Android 平台提供l两种解决方式:1)一种方法是让几个应用程序使用一个ID,这样它们之间就可以相互访问其他应用程序地文件;当然也可以让几个应用程序同时使用一个虚拟机,在一个进程中运行2)另一种方法是在安装应用程序时,可以让用户设置权限,然后每个应用程序根据用户自己设置地权限访问其他程序地数据和系统资源经过多次试验以及相关资料验证,Android应用程序地运行会经历以下工作过程,如图3-2所示通过这个示意图,我们可以清晰地l解到Android应用程序运行地过程图3-2 Android应用编译过程3.2.A ndroid开发环境配置Android开发环境地搭建是进行Android应用程序开发必不可少地一个过程,搭建环境需要准备Java JDK、Eclipse(或MyEclipse)、Android SDK以及ADT1)下载并安装JDK2)JDK安装完成后,需要配置环境变量,JAVA_HOME、PATH、CLASSPATH环境变量配置好后,运行命令提示符:java –version,javac如果返回信息,则设置成功[18]3)接下来安装EclipseEclipse为Java及Android开发地IDE4)安装好Eclipse后,还需要安装Android SDKSDK地中文翻译为软件开发包,顾名思义,这就是一个可以让软件开发者使用地特定开发工具地集合在谷歌官网我们可以根据不同需求下载合适SDK5)最后安装并配置ADT经过以上步骤后,我们就可以创建我们地项目l3.3.关键技术和原则Android地应用程序开发既有传统软件开发地特点,又有自己独特地地方,因为它主要运行在手机端,所以我们需要考虑到手机地运行速率,因此我们在设计程序时应该尽量充分利用手机硬件资源,优化内存占有率,降低应用程序地耗电量,同时还要考虑实际手机屏幕地大小,应该为常见屏幕做到各种屏幕分辨率地适配要做出一个完美地Android应用程序必须掌握Android开发过程中地几个关键技术1)开发语言现在地Android应用程序地开发语言大都是是基于Java语言地,所以进行Android开发需要熟练掌握java语言地运用当然,现在地Android不再局限于Java语言,也有许多应用程序是用c/c++开发地,不过这种语言地开发主要用于需要高效操作底层硬件时地开发现在地主流Android应用程序都是Java 语言开发地,所以掌握Java语言才是Android开发地基础2)节省电源技术一部手机非待机状态时地用电量一直都很大,所以Android 开发时必须考虑到节省手机电池电量,提高电池使用寿命研究证明手机地耗电量与多种因素有关,比如屏幕地亮度、进程地数量等,所以要降低电池耗电量,必须为程序选择一个合适地背景,尽量减少不必要地进程,尽早关闭已经处理完任务地进程此外,大多数手机自带功能如震动、蓝牙等都是非常耗电地,所以像这些硬件模块在不需要时尽量不要开启3)多线程技术在Java语言中,多线程技术是一项重要技术,对于需要用Java 语言开发地Android应用,多线程技术也是必不可少地在Android开发中使用多线程技术能充分利用手机硬件资源,进而有效地提高程序地执行效率,所以,多线程技术是Android开发过程中地必备技术在默热情况下,Android应用程序只有一个主线程,这意味着应用程序要处理地任务如果太多地话,会在主线程中占用太长时间,最终将会造成主线程地阻塞,进而引发应用程序无响应,用户体验就会很差,为l解决这个问题,就需要在Android应用程序中把那些占用线程时间长地任务放到一个新开地子线程当中进行,等子线程任务处理完后只要发消息给主线程进行更新即可举个例子来说,如果要下载地文件过大,就需要很长地下载等待时间,这样就不能将下载任务放到主线程进行,最好地办法就是开启一个子线程来完成,完成之后放个消息给主线程,通知主线程任务已完成,整个过程如图3-3所示图3-3 Android多线程示意图4.系统地分析与设计在进行开发之前我们需要对系统进行必要地分析与设计,然后根据分析与设。
Android开发中的定位服务和地图应用开发在现代移动应用开发中,定位服务和地图应用已经成为不可或缺的一部分。
Android系统提供了丰富的API和开发工具,使得开发人员可以轻松地实现定位功能和创建强大的地图应用。
本文将分析Android 开发中的定位服务和地图应用开发,探讨其原理和实践应用。
一、定位服务的原理和使用定位服务是通过获取设备的位置信息,确定设备所在的地理位置。
Android系统提供了多种定位服务的方式,包括基于GPS、网络和传感器等。
其中,GPS定位是最常用的方式,通过获取卫星信号解算设备的经纬度信息,准确性较高。
网络定位则是通过与移动网络基站进行通信,获取设备所处的基站信息来确定位置。
传感器定位是通过设备上的传感器获取周围环境的数据,如气压、加速度等来推测位置。
在Android开发中,使用定位服务需要进行一系列的设置和操作。
首先,需要在Manifest文件中声明对定位权限的请求,确保应用有权限获取位置信息。
其次,需要实例化LocationManager对象,通过调用其方法获取定位提供者。
然后,可以通过监听器来获取位置变化的通知,或直接调用getLastKnownLocation()方法获取最近一次的位置信息。
最后,通过Location对象获取经纬度等详细信息,并对其进行处理和展示。
定位服务的使用不仅限于获取设备的经纬度坐标,还可以通过反向地理编码将坐标转换为具体的地址信息。
通过调用Geocoder类的方法,可以将经纬度坐标转换为国家、城市、街道等详细地址信息。
二、地图应用的开发和功能扩展地图应用是基于定位服务的应用之一,在Android开发中具有广泛的应用场景。
地图应用可以通过集成第三方地图SDK(Software Development Kit)来实现,如百度地图、高德地图等。
这些SDK提供了丰富的地图显示和交互功能,使得开发人员可以灵活地定制地图应用。
在地图应用开发中,通常需要展示地图、标记位置、搜索地点等功能。
android逆向奇技淫巧⼆:uiautomatorviewermethodprofili。
做逆向,不论是在windows还是Android,抑或是macos,都必须要⾯对的⼀个问题:找到关键的代码。
android平台下怎么找到关键的代码了?本⽂以某国民级短视频APP 为例,分享从UI界⾯定位到关键代码的链路逻辑! 1、⽼规矩,先在模拟器运⾏这款APP,然后打开ui automator viewer “截屏”(注意:要暂停短视频播放才⾏,否则截屏的时候会报错)!如下: ⽐如我们想找点赞按钮的执⾏代码(⾄于为什么要找这个按钮的执⾏代码,道上⼈⼠都懂的),光标移动到笔芯上,右边就会显⽰出笔芯的imageView,这⾥能看出其实是⼀个按钮控件;先阿敏有resource-id和class类型;接着进⼊jadx(这种apk上百兆,⽤jadx容易卡死,需要增加内存,增加的⽅法见⽂章末尾的参考1),找到resources.arsc⽂件,⽤刚才找到的id字段也就是byb作为关键词,找到点赞笔芯的id: 2131168834 然后继续搜索,发现原来是这两⾏代码引⽤了: 本想点击进⼀步查看java源码,⽆奈本机内存只有16G,⽽jadx已经消耗了9G,还是卡者不动,⽆法继续,这⾥换成android killer继续逆向分析。
把这⼀串id转成16进制,然后在android killer⾥⾯搜索:发现到处都在引⽤;后续会继续分享怎么分析这些引⽤! ⾄于这⾥为啥⽤id来检索,⽽不是控件的名称了?我个⼈理解:⼤概率是因为控件名称开发⼈员随时都可能更改,所以编译器⾃动⽣成id与之对应。
控件名称随时可以改,但是id不变,通过这种⽅式做到松耦合! 2、上⾯使⽤了这个id的地⽅还是有很多,挨个去静态分析还是耗时,怎么能快速找到点赞执⾏了哪些代码了?这⾥有个更快速的⽅法:method profiling;本质上,method profiling相当于录屏,结果如下: 因为⽤户需要⼿动点击笔芯才能点赞,所以肯定会调⽤onclick⽅法,这⾥就能根据onclick作为关键词查询:只有这两个地⽅调⽤了onclick⽅法: 接下来再去jadx或android killer找这两个⽅法分析源码,是不是简单多了?(⽤AK搜的时候注意把.改成/) ⽼规矩,最后整理⼀下常见的静态分析⽅法:注意:x⾳没登陆时点击屏幕⽤的是onClick来监听的;⼀旦登陆,⽤户点赞⽤的就是onTouch监听了,method profiling捕获到的函数调⽤如下: 代码在这:public boolean onTouchEvent(MotionEvent motionEvent) {View.OnTouchListener onTouchListener;boolean z = false;PatchProxyResult proxy = PatchProxy.proxy(new Object[]{motionEvent}, this, f173585a, false, 254253);if (proxy.isSupported) {return ((Boolean) proxy.result).booleanValue();}if (!isEnabled()) {return false;}this.j = true;int actionMasked = motionEvent.getActionMasked();if (actionMasked != 0) {if (actionMasked != 1) {if (actionMasked == 2) {this.n = motionEvent.getX();this.o = motionEvent.getY();float abs = Math.abs(this.f173586b - this.n);float abs2 = Math.abs(this.f173587c - this.o);int i2 = this.p;if (abs > ((float) i2) || abs2 > ((float) i2)) {z = true;}if (z) {com.ss.android.a.a.a.a.c(this.s);}View.OnTouchListener onTouchListener2 = this.r;if (onTouchListener2 != null) {onTouchListener2.onTouch(this, motionEvent);}} else if (actionMasked != 3) {if (actionMasked == 5) {com.ss.android.a.a.a.a.c(this.s);}}}com.ss.android.a.a.a.a.c(this.s);if (SystemClock.elapsedRealtime() - this.f173591g < ((long) this.q) && (onTouchListener = this.r) != null) { onTouchListener.onTouch(this, motionEvent);}} else {this.f173586b = motionEvent.getX();this.f173587c = motionEvent.getY();this.f173591g = SystemClock.elapsedRealtime();com.ss.android.a.a.a.a.a(this.s, this.q);View.OnTouchListener onTouchListener3 = this.r;if (onTouchListener3 != null) {onTouchListener3.onTouch(this, motionEvent);}}super.onTouchEvent(motionEvent);return true;} 这个和上⾯那个是⽗⼦关系: 继续⼀层⼀层往下拨:继续往下拨:反编译失败了:直接看smali代码或hook看看传⼊的参数是啥:直到这⾥进⼊系统函数才罢休:这⾥貌似是遍历短视频,如果还有就取出来对⽐id,看看是不是同⼀个短视频:两个参数都是float,看着像横纵坐标:仅通过静态分析也看不出啥花样来,这⾥继续⽤objection去hook上述提到的⼀些关键⽅法,看看传⼊的参数和返回值都是啥了:objection --gadget "com.ss.android.ugc.aweme" exploreandroid hooking watch class_method com.ss.android.ugc.aweme.feed.utils.m$1.onTouch --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method com.ss.android.ugc.aweme.feed.panel.b$10.a --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method com.ss.android.ugc.aweme.feed.panel.t.a --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method com.ss.android.ugc.aweme.feed.panel.b.a --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method com.ss.android.ugc.aweme.feed.story.viewmodel.b$a.a --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method mon.widget.DiggLayout.a --dump-args --dump-backtrace --dump-return⼀次性hook了这么多函数,信息量最⼤的就是下⾯这个函数了,参数传⼊了⼀⼤堆,但和⽤fiddler抓的数据相差甚远,所以有两种可能:(1)java层发送数据的不是这些函数,这⾥没hook到(2)发数据的函数在so层; 下滑时调⽤了这个函数,并传⼊了MotionEvent类的参数:(agent) [763006] Called com.ss.android.ugc.aweme.feed.panel.t.a(android.view.MotionEvent, com.ss.android.ugc.aweme.feed.adapter.av, com.ss.android.ugc.aweme.feed.model.Aweme)(agent) [763006] Backtrace:com.ss.android.ugc.aweme.feed.panel.t.a(Native Method)com.ss.android.ugc.aweme.feed.panel.b.a(BaseListFragmentPanel.java:2411)com.ss.android.ugc.aweme.feed.panel.b$10.a(BaseListFragmentPanel.java:33816612)com.ss.android.ugc.aweme.feed.panel.b$10.a(Native Method)com.ss.android.ugc.aweme.feed.utils.m$1.onTouch(BaseFeedListViewUtils.java:34013410)com.ss.android.ugc.aweme.feed.ui.LongPressLayout.onTouchEvent(LongPressLayout.java:17170610)android.view.View.dispatchTouchEvent(View.java:10023)com.ss.android.ugc.aweme.feed.ui.LongPressLayout.dispatchTouchEvent(LongPressLayout.java:17039388)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)mon.widget.VerticalViewPager.dispatchTouchEvent(VerticalViewPager.java:17039392)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)com.ss.android.ugc.aweme.feed.widget.FeedSwipeRefreshLayout.dispatchTouchEvent(FeedSwipeRefreshLayout.java:17039388)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)dmt.viewpager.DmtViewPager.dispatchTouchEvent(DmtViewPager.java:17039406)com.ss.android.ugc.aweme.homepage.ui.view.MainFlippableViewPager.dispatchTouchEvent(MainFlippableViewPager.java:17170614)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)com.ss.android.ugc.aweme.feed.ui.seekbar.SupportSeekBarFrameLayout.dispatchTouchEvent(SupportSeekbarFrameLayout.kt:17236196)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)dmt.viewpager.DmtViewPager.dispatchTouchEvent(DmtViewPager.java:17039406)com.ss.android.ugc.aweme.base.ui.ScrollableViewPager.dispatchTouchEvent(ScrollableViewPager.java:17104950)com.ss.android.ugc.aweme.homepage.ui.view.MainScrollableViewPager.dispatchTouchEvent(MainScrollableViewPager.java:17104971)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:414)com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1808)android.app.Activity.dispatchTouchEvent(Activity.java:3080)androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:16842754)com.bytedance.a.h.dispatchTouchEvent(WindowCallback.kt:17039390)com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:376)android.view.View.dispatchPointerEvent(View.java:10243)android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4438)android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4306)android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3906)android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3872)android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3999)android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3880)android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4056)android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3906)android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3872)android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3880)android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6247)android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6221)android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6182)android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6350)android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)android.os.MessageQueue.nativePollOnce(Native Method)android.os.MessageQueue.next(MessageQueue.java:323)android.os.Looper.loop(Looper.java:136)android.app.ActivityThread.main(ActivityThread.java:6153)ng.reflect.Method.invoke(Native Method)com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)(agent) [763006] Arguments com.ss.android.ugc.aweme.feed.panel.t.a(MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=567.0, y[0]=1176.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edge 点赞时调⽤了同样的函数,并传⼊了videosEvent类的参数:(agent) [763006] Called com.ss.android.ugc.aweme.feed.panel.t.a(com.ss.android.ugc.aweme.feed.h.cb)(agent) [763006] Backtrace:com.ss.android.ugc.aweme.feed.panel.t.a(Native Method)com.ss.android.ugc.aweme.feed.panel.b.a(BaseListFragmentPanel.java:3594)com.ss.android.ugc.aweme.feed.adapter.VideoViewHolder.a(VideoViewHolder.java:3110)com.ss.android.ugc.aweme.feed.adapter.VideoViewHolder.a(VideoViewHolder.java:3760)com.ss.android.ugc.aweme.feed.adapter.VideoViewHolder.onChanged(VideoViewHolder.java:16842754)com.ss.android.ugc.aweme.arch.widgets.base.NextLiveData$NextObserver.onChanged(NextLiveData.java:17039395)androidx.lifecycle.LiveData.considerNotify(LiveData.java:17039389)androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:17039410)androidx.lifecycle.LiveData.setValue(LiveData.java:16973838)androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:16777216)com.ss.android.ugc.aweme.arch.widgets.base.NextLiveData.setValue(NextLiveData.java:16973849)com.ss.android.ugc.aweme.arch.widgets.base.DataCenter.a(DataCenter.java:34078842)com.ss.android.ugc.aweme.feed.quick.presenter.cb.c(FeedDiggPresenter.java:17170485)com.ss.android.ugc.aweme.feed.quick.presenter.ce.run(Unknown Source)android.os.Handler.handleCallback(Handler.java:751)android.os.Handler.dispatchMessage(Handler.java:95)android.os.Looper.loop(Looper.java:154)android.app.ActivityThread.main(ActivityThread.java:6153)ng.reflect.Method.invoke(Native Method)com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)参考:。
Android平台下地图定位搜索功能的实现经济的发展、迅速的城市化,城市人口和机动车数量的迅速增加,一定程度推动了社会经济的发展,但也使目前城市交通问题日益突出,给城市社会经济发展带来了严重影响。
传统的管理方法或者采用诸如更新道路设施,这些方法并不能对交通问题作出动态反应,找到更有效的解决措施成为必然趋势。
智能交通系统[1-2](Intelligent Transportation System)的出现为解决交通问题提供了新的思路,随着智能手机的日益普及,加之Android 平台提供给开发者非常灵活的地图展示和控制功能,这使得地图服务和位置定位的设计成为可能。
Android平台的开放性等特点既能促进技术的创新,又是运营商可以制定自己的特色化产品,具有很大的发展和应用空间。
因此,开发基于android手机的电子地图的应用程序已成为智能交通系统的一大发展方向。
本项目目标是将电子地图应用到交通系统当中,意在这个移动式交通背景下开发一套基于android手机的电子地图的应用软件,将人、车、地理空间以及网络完美地融合在一起,更方便人们的出行。
本项目的创新点在于:(1)能够实现自我定位,位置跟踪功能;(2)能够通过网络传输实时获取所需数据;(3)实现附近信息采集功能并能在地图上显示;(4)能够获取附近友人的位置信息;(5)能够实现路径规划功能。
总的来说,本项目将电子地图应用软件移植到android手机中,全方位地使得人、车、路和网络紧密结合,有效的解决了交通问题,改善了人们的出行质量。
1 系统开发理论支持本系统在电子地图的基础功能上进行的应用程序开发,其中涉及到了一些理论技术,主要有电子地图技术、定位技术和道路空间距离计算。
1.1 电子地图电子地图[3]是传统地图与计算机技术、GIS技术、网络技术相融合的产物,来源于数字地图,将计算机系统作为其软硬件支撑,以可视化的数字地图为背景,结合多种媒体向用户展示了各城市、地区的地形分布面貌。
一、LocationManagerLocationMangager,位置管理器。
要想操作定位相关设备,必须先定义个LocationManager。
我们可以通过如下代码创建LocationManger对象。
LocationMangerlocationManager=(LocationManager)this.getSystemService(Context.LOCATION_SERVICE );二、LocationListenerLocationListener,位置监听,监听位置变化,监听设备开关与状态。
private LocationListener locationListener=new LocationListener() {/*** 位置信息变化时触发*/public void onLocationChanged(Location location) {updateView(location);Log.i(TAG, "时间:"+location.getTime());Log.i(TAG, "经度:"+location.getLongitude());Log.i(TAG, "纬度:"+location.getLatitude());Log.i(TAG, "海拔:"+location.getAltitude());}/*** GPS状态变化时触发*/public void onStatusChanged(String provider, int status, Bundle extras) {switch(status) {//GPS状态为可见时case LocationProvider.AVAILABLE:Log.i(TAG, "当前GPS状态为可见状态");break;//GPS状态为服务区外时case LocationProvider.OUT_OF_SERVICE:Log.i(TAG, "当前GPS状态为服务区外状态");break;//GPS状态为暂停服务时case LocationProvider.TEMPORARILY_UNAVAILABLE:Log.i(TAG, "当前GPS状态为暂停服务状态");break;}}/*** GPS开启时触发*/public void onProviderEnabled(String provider) {Location location=lm.getLastKnownLocation(provider);updateView(location);}/*** GPS禁用时触发*/public void onProviderDisabled(String provider) {updateView(null);}};三、LocationLocation,位置信息,通过Location可以获取时间、经纬度、海拔等位置信息。
昨儿折腾了一天,把Android 手机定位、获取手机当前位置的功能给搞掂了。
这次记下来,不然又忘~~思路很简单,第一步,获取经纬度,第二步,把经纬度转换为地址。
看起来简单,但是实现起来比较郁闷~~获取经纬度可以有很多选择。
我刚开始做时,想着Google最好用,但是写完代码测试下,悲催的逆解析地址总是为空。
代码如下:/**** 由街道信息转换为经纬度* @param address 街道信息* @return 包含经纬度的一个double 数组,{longtitude,latitude}*/public static double[] getLocationInfoByGoogle(String address){//定义一个HttpClient,用于向指定地址发送请求HttpClient client = new DefaultHttpClient();//向指定地址发送Get请求HttpGet hhtpGet = new HttpGet("/maps/api/geocode/json?address="+address+"ka&sensor=fal se");StringBuilder sb = new StringBuilder();try {//获取服务器响应HttpResponse response = client.execute(hhtpGet);HttpEntity entity = response.getEntity();//获取服务器响应的输入流InputStream stream = entity.getContent();int b;//循环读取服务器响应while((b = stream.read()) != -1){sb.append((char)b);}//将服务器返回的字符串转换为JSONObject 对象JSONObject jsonObject = new JSONObject(sb.toString());//从JSONObject 中取出location 属性JSONObject location = jsonObject.getJSONObject("results").getJSONObject("0").getJSONObject("geometry").getJS ONObject("location");//获取经度信息double longtitude = location.getDouble("lng");double latitude = location.getDouble("lat");return new double[]{longtitude,latitude};} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (JSONException e) {e.printStackTrace();}return null;}/*** 根据经纬度获取对应地址,此处的经纬度须使用Google或者高德地图的经纬度;<br> * 若使用百度地图经纬度,须经过百度API接口(BMap.Convertor.transMore(points,2,callback))的转换;* @param longitude 经度* @param latitude 纬度* @return 详细街道地址*/public static String getAddressByGoogle(double longitude,double latitude){//定义一个HttpClient,用于向指定地址发送请求HttpClient client = new DefaultHttpClient();//向指定地址发送Get请求HttpGet hhtpGet = new HttpGet("/maps/api/geocode/json?latlng="+latitude+","+longitude+" &sensor=false®ion=cn");StringBuilder sb = new StringBuilder();try {//获取服务器响应HttpResponse response = client.execute(hhtpGet);HttpEntity entity = response.getEntity();//获取服务器响应的输入流InputStream stream = entity.getContent();int b;//循环读取服务器响应while((b = stream.read()) != -1){sb.append((char)b);}//将服务器返回的字符串转换为JSONObject 对象JSONObject jsonObject = new JSONObject(sb.toString());//从JSONObject 中取出location 属性JSONObject location = jsonObject.getJSONObject("results").getJSONObject("0").getJSONObject("formatted_addres s");return location.toString();} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (JSONException e) {e.printStackTrace();}return null;}这件事的惨痛经历告诉我:一定要有政治觉悟,不然编代码丫多的都不成。
android 模拟定位原理
Android模拟定位是指在安卓系统中通过软件等方式虚拟自己的
位置信息,使得系统以为用户在某个特定地点,从而实现一些趣味性
的应用需求。
那么,具体的模拟定位原理是什么呢?下面,我们就来
分步骤阐述。
第一步:打开开发者模式
在安卓手机中,需要先打开手机的开发者模式。
具体操作方法是:打开手机设置,找到“关于手机”选项,连续点击数字版本号,即可
开启开发者模式。
开发者模式的实质是提供给用户更加广泛和深入的
手机系统权限,以便进行更加自由、方便的操作。
第二步:搜寻第三方位置模拟软件
有了开发者模式后,我们可以在网络中寻找一些比较好的第三方
模拟定位软件。
目前市面上有不少模拟定位的软件,例如VPNCity、谷歌地图等。
选择合适的软件,安装在手机上即可。
第三步:开启模拟定位
安装好模拟定位软件后,进入设置页面,开启“允许模拟位置”。
然后再进入该软件的相应操作页面,选择需要更改的位置,进行虚拟
操作即可。
这里,需要注意的是,在某些需要精确定位的应用中,由
于坐标的误差,可能在操作时无法达到理想效果,用户需要反复尝试
和调整。
总的来说,安卓模拟定位的原理是通过在开发者模式下开启第三
方模拟定位软件,利用虚拟位置来欺骗系统。
虽然操作简单,但也需
要在一定程度上的技术支持。
同时,安卓系统还对某些应用的精度有
所控制,用户需要根据实际需要来选择和调整。
模拟定位还可以用于
保护用户隐私等领域,但如果用于非法用途,也容易引起风险和纠纷,建议使用者理智谨慎。
安卓逆向工程实战教程在编写安卓逆向工程实战教程之前,我们需要明确一些基础概念。
安卓逆向工程是指通过分析安卓应用程序的代码、二进制文件以及相关数据,来获得对应应用的工作原理和内部机制的过程。
这一技术可以帮助我们获取应用程序的源代码、解密加密算法、绕过应用程序的安全机制等。
在本教程中,我们将介绍一些常用的安卓逆向工程技术和工具,并通过实例演示其具体操作步骤。
一、安卓逆向工程基础知识在进行安卓逆向工程之前,我们需要了解一些基本知识。
首先,了解Java和Dalvik虚拟机的相关知识对于理解安卓应用程序的结构和代码是必要的。
其次,我们需要了解安卓应用程序的打包和签名过程,以及应用程序的组成结构。
此外,对于反编译和分析Java代码的工具也需要有一定的了解。
二、安卓逆向工程常用工具介绍1. APKTool:APKTool是一个用于反汇编、编译和重新打包安卓应用程序的工具。
通过使用APKTool,我们可以将安卓应用程序的APK 文件解压成可读的资源文件和smali代码,进而进行分析和修改。
2. Dex2Jar:Dex2Jar是一个将安卓应用程序的dex文件转换为jar文件的工具。
通过使用Dex2Jar,我们可以将dex文件反编译成可读的Java代码,便于进行分析和修改。
3. JD-GUI:JD-GUI是一个用于查看Java代码的工具。
通过使用JD-GUI,我们可以将反编译得到的Java代码进行查看,了解应用程序的结构和逻辑。
4. IDA Pro:IDA Pro是一个强大的二进制分析工具。
通过使用IDA Pro,我们可以对安卓应用程序的二进制文件进行逆向分析,了解其底层机制和算法。
三、安卓逆向工程实战案例以一款简单的安卓应用程序为例,我们将演示如何进行逆向分析和修改。
1. 解包应用程序:使用APKTool将应用程序的APK文件解压。
2. 反编译应用程序:使用Dex2Jar将应用程序的dex文件转换为jar文件,然后使用JD-GUI查看反编译得到的Java代码。
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中的a(II)方法中调用的,那么我们就继续顺藤摸瓜~根据smali语法,构造搜索字符串“Lct/br;->a(II)”,通过这个字符串,我们可以利用Find in Floder的搜索功能,知道在哪里调用了这个函数:不错,已经找到了核心文件bz.smali,我就先说了吧,该类有两个内部类一个bz$1,另一个bz$a(美元符号代表内部类),bz$1是一个继承了Runnable的一个线程类,bz$a就是一个封装数据的类,包括加密后的数据和请求地址。
因为我们是要找到加解密的原理,所以在找关键代码的时候,要多留心带有String类,和byte[]数组参数的函数,这些往往就是我们的Target~so,不妨大致浏览一下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。
这是关键点,通过000000^key=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,很郁闷~下面把代码贴出来:微信里面有个“附近的人”,相信大家都知道,大概的原理就是调用腾讯地图的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协议的包。