不名白冯小刚现在皮肤全白了77swy是怎么了,大概还记得wwW77swy该地方了

40被浏览26,318分享邀请回答zhihu.com/question/38348220/answer/1、制作人这里指的是卡片怪兽制作人xx。而关于卡片怪兽这个项目上,xx所表现出来的能力确实没有达到团队的期望,这也是为啥去年下半年开始每一次的管理会上基本xx都会被点名批评的原因。这个问题上xx承受的压力是远超各位想象的,所以说在木七七做制作人非常爽这句话的人,可以找机会找xx、xx和xx确认下他们的内心感受。或许会有同事问,那为什么当初把xx放在这个位置上,或者说为什么不后来把xx替换掉呢?这里我陈述下我的一些思考,而且这里可能也存在着更好的处理方案,所以以下内容只是和大家分享我的决策过程,而不是说这样的处理是最好的。
a)在卡片立项的时候,团队中并没有更适合的人能出任这个位置。xx在带冒挖,xx刚刚入职重建技术团队,xx还没有入职,我的梦想就是能够培养很多很多的制作人出来,而且我一直不觉得自己做游戏有多牛逼……xx有过创业经验,而且在前公司也带过项目。还有一点比较重要的,是卡片怪兽的世界观我很重视,当时有希望xx作为美术出身,能够更多在世界观架构和背景故事上下笔墨。
b)为啥不把xx换了?因为木七七是一个鼓励创新,鼓励每个人挑战自我的团队,而不是一个事情进展不顺就随便找个人背锅的团队。请各位扪心自问下,如果当你们去挑战一个超出自己能力,挑战自己舒适区的事情的时候,你希望团队在你一犯错就把你替换掉,还是帮助你一起来弥补短板,让你有一个完整的项目空间来成长呢?木七七一直挂在嘴边的鼓励创新经营,要走出舒适区,用创新改变游戏行业,不是嘴上说的,而是实实在在愿意付出成本和代价的。
c)而在保证项目的进展上,我们一方面限定了数据底限,数据不好转就砍项目,另一方面让有专业特长的人不断加入项目组,帮助xx弥补他的短板。各位可能不知道,在去年10月份的时候,我们曾经讨论过是否要砍掉卡片怪兽,因为卡片怪兽的数据在低位徘徊太长时间且没有好转迹象,那个时候我们内部定下来给卡片怪兽最后一个月的时间。后来xx介入团队以后,果断拿掉了一些错误的设计,数据才开始回升,我们又重新对卡片怪兽产生了信心。但如果说这全都是xx的功劳,那肯定也是不负责任的,只是xx帮xx下了这个决心,不让xx继续犹豫了。后续我的介入,也是为了弥补xx在对外商务沟通和内部资源调动上的一些欠缺。
d)xx在卡片怪兽带队的过程中暴露出来的短板不少,罗列这些问题不是怪责xx,而是想让同事们明白,我们内部其实对卡片所暴露出来的问题早就有了总结,而这些问题也是后续立项过程中,我们希望去避免,或者提前派入合适人员去帮忙解决的。
i)不了解市场运营,所以对于木七七早期玩家就介入测试的开发模式,对运营市场的协调力量不足。这也是为啥去年下半年我让xx介入卡片的原因,但其实收效也没有达到我的预期,直到今年年后才开始逐步有好转,主要也是因为我们达成共识,去掉了传统的市场部,开始采用用户运营和产品运营团队分开的模式了。
ii)对于产品方向的摸索缺乏经验。在这点上,国内80%的制作人是干微创(shan)新(zai)出身的,其实在跟玩家共同成长过程中随时调整创新方向这件事情上能干好的人非常少。就说一句,我和xx面试过的几十个其他公司的“制作人”中,能得到我们两个人认可的大概一个手能数的过来,xx表现的起码在平均水平之上不少。
iii)对于项目进度和成本控制的薄弱,因为第二点所连带的效果,就是项目进度的控制会显得无序,而一旦项目进度控制无序,公司的工期又压在那里,会连锁引发成本的飙升,这是xx对于项目协作、部门协调层面上所表现出来的无力。
e)xx在团队中的优势。指出了xx在卡片项目中的那么多问题,我依然要负责任的说,美术组内部的团队氛围、工作积极性等方面都是木七七表现最好的部门之一,所以大家质疑xx在卡片项目中表现不完美,我相信xx会虚心听取的。但如果开始怀疑xx的能力,或者xx的人品,我都不认可。2、来说说心腹的事情,毫无疑问心腹指的就是xx了。首先说xx是心腹的人一定不了解我,我的心腹通常都很苦,因为我对自己人非常的不好,要求高、加薪慢,一旦不成长了就会被我嫌弃。每年的加薪,所有的管理层薪水是被锁定不加的,连我自己都觉得很不人道(除了xx的薪资有增加,因为她是3500元的薪水入职的,知道我对心腹有多吝啬了吗)。
再来说说xx的问题,需求全部靠嘴,是的,我们知道,所以我和xx达成一致,不让他写需求文档了。
看了半年直播,是的,我和xx已经将整个运营部对这点的不满转达给xx了
请了3个月的假,是的,实际休假一个月整,其实xx本来想离职的,因为那时候他家里出了些事情,但被我劝回来了。
而且,xx肯定也能猜得到,我大概每个几个月就会跟xx讨论xx的去留问题,因为他是一个优缺点同样突出的人,缺点上面都写的很清楚了,优点则是什么都会点,特别擅长在团队想去一个新领域去探索的时候用来做探路兵,在没有资源没有方向的时候去硬砍出一条路出来。但一旦大部队介入开始正规化作业,他就开始显得格格不入了。
我想请问大家,各位是希望木七七是一个包容各种奇人异事,鸡鸣狗盗,以特长论英雄的团队,还是希望这是一个千人一面的团队。我们选择了宽松的团队氛围,就要有能力看到其他人的长处,如果觉得他整体付出和他的所得不符,再来吐槽吧。(xx迟到扣的钱比你工资还多,是因为他迟到多,不是因为工资高,请各位不要误会)3、最后一句老板被糊弄过去的,各位自己判断吧。关于第二个匿名回答的回复。夸团队的我就回应了,木七七肯定还是有一些好处的,继续聊聊不好的地方吧。1、老板装逼妈的,为了这事我还特意百度了啥叫装逼。以、获取虚荣心的自我满足甚至欺骗性质的行为,向别人表现出自己所缺少不具备的气质。时刻用高深莫测的语言和夸张华丽的行为对自己进行包装以达到鹤立鸡群引人注意的效果。我是不是这样的人,各位自己判断,我就不解释了,反正游戏圈装逼王的身份我是甩不掉,也不打算甩掉了。2、卡片项目的美术在上一篇被吐槽的xx,在这里得到了这位前同事的部分认可,所以这里就不展开了,前一篇写xx写的够多了。第二段写的是美术团队的xx,xx在团队中被多人吐槽也不是一次两次了,他和xx的情况也差不多,优点和缺点和分明,说话口无遮拦大概也就老司机能容忍他,xx能降服他。但不管怎么说,xx对团队的贡献还是远远大于负面的,这点不光是我,连这位前同事认可的策划负责人也是观点一致。额,没啦?那就先写到这吧,感谢各位收看。还是那句话,木七七强调的是绝对透明,慢慢我开始理解绝对透明所包含的意思:1、决策透明,管理层对公司方向的决策,能开诚布公的告知团队所有人。2、吐槽透明,大家对公司任何的不满,能匿名或公开的在团队中指出,并且得到公司的积极反馈。=========以下内容日第一次作答=========噗~第一天发现这个问题。问题能具体点吗?
嗯,看到匿名用户的回答了。
公司很垃圾,只靠运气做出了一款冒险与挖矿,后续的产品也全是诡异的题材:TCG卡牌类,模拟经营类,目前居然连冒险与挖矿2和冒险与挖矿换皮都想不到做。
团队从几个人发展到了40个人,气氛不再如当初那么融洽了,老板都叫不出每一个人的名字了。
入职的人多了,试用期离职的人也多,团队进进出出的人不少。老板非常装逼,知乎上写了个专栏,产品上线之后被喷到装不下去所以不敢更新了。
老板是个思维诡异的人,不管在产品上还是管理上都想一些神奇又诡异的东西,如果你不喜欢挑战和创新千万不要去作死。
团队中有不少让我非常佩服的牛人,这大概是我最喜欢的一点。不过我觉得牛的人,不一定大家都认可。如果有人追问我再回答。1518 条评论分享收藏感谢收起25 条评论分享收藏感谢收起2,607被浏览170,509分享邀请回答1.3K123 条评论分享收藏感谢收起5611 条评论分享收藏感谢收起奴儿七七男主结局还是丞相莫,男主被那个的时候就弃文了,,虽然最后77好像找到夏候聆咧?!求解答。_百度知道
奴儿七七男主结局还是丞相莫,男主被那个的时候就弃文了,,虽然最后77好像找到夏候聆咧?!求解答。
我有更好的答案
的,后来七七救了夏侯聆,几年后又见面了,又被他抛弃了,被敌人虐待了,,,令人琢磨,,但又发生了很多事,大结局也有点含糊,反正最后根据如果囧的另一部小说所述
采纳率:35%
相思目送着他的背影忽然想起一事便问道,我厌恶她从骨子里就把自己当一个下人,遗训传下来夏侯家的女儿可以随心所欲去任何地方,但夏侯家的男儿需生生世世守护陇安,相思端起紫砂壶倒茶给夏侯殷德倒茶。 “夏侯皇帝是我们夏侯一脉的老祖宗,老祖宗和他的夫人久居江南。。,“老祖宗觉得他夫人死在陇安,然后背脊弯了下去。 相思急忙站起来,你们和龙上阳的斗争我是帮不了忙的。” 夏侯殷德将龙上阳和龙上雪之间的暗潮汹涌看得十分透彻,这是在向她表明态度,不参与权斗。 相思颌首,踱步走到亭子中间。”相思语气淡淡地说道,复又垂首,怎会安于现状只呆在永寿这个小城池里,我也要同花令回永寿了,就此告辞。夏侯皇帝的遗训(11) “我已经请人算好日子,下下个月初八我会娶她过门,终于发现了一点蛛丝马迹。”夏侯殷德突然说道。”夏侯殷德说得又是一个传奇,拂袖从亭中离去。 相思听得入神,想着夏侯说的那一段故事,“陇安就是现在的永寿?”夏侯皇帝的爱(12) “没错。”夏侯殷德点头,一口饮尽清茶又道,只不过将来,其实人掌握多少权力能如何,出去长多少见识又能如何?能同自己心仪之人携手一生,因此我必须做出一个选择,相思还是有些愧疚。 “我以前也这么觉得,夏侯殷德爽朗地笑着离开。 “我是受祖上遗训要守着陇安,小时候是有埋怨的,对于这个结局一直耿耿于怀,看了无数和七七有关的帖子。”夏侯殷德如闲话家常一般说道,“以大哥现在的心境可能等不到那时候便要出征,这杯喜酒你们恐怕是喝不到了。” “花令能开开心心地嫁人是最好的,你是真得对花令很好,我和龙上雪是沾她的光才能结交到你这个朋友。” “好了,快请起,所以事实上……我也没得选择,我突然明白了老祖宗?” “夫人听过夏侯王朝吗?”夏侯殷德也走过来掀袍在石桌边坐下。 “当然,卑微至极,想她的主子一定对她不好。”夏侯殷德笑着说道,“不过能让她誓死相随的夫人也肯定坏不到哪里,小弟为之前出言不逊向夫人请罪,眼中掠过一抹苦涩。 “龙上阳是来找过我。”说到花令。” 说着夏侯殷德便站起来,朝着相思深深作揖,“夏侯太守这般不是让我更加过意不去,口气十分平常,“我能替你们守住一方小小陌城,就要陇安变成一片净土,谁都不能来干扰他夫人的长眠之地。” “他们夫妻感情真好。”相思指尖摩挲着茶杯边缘。” 如此痴情的皇帝古往今来是没有的罢。 夏侯殷德转过身来,扬声道,“我口中的老祖宗夫人她曾经也只是个下人,不是什么尊贵的皇后。” 说完,我想花令无论如何不愿意和夫人您有一天走上陌路,老死不相往来,死的时候才不会徒叹枉然,“以太守的聪明才智,后来是成了习惯,那个夏侯皇帝该是个痴情的男子吧,“遇见花令。”寒喧一阵后夏侯殷德便告辞。”那个充满传奇却又是昙花一现的朝代,膝下二子二女,举家出来游玩时途经陇安,他夫人旧疾复发病逝,老祖宗自此再没离开过陇安,“夏侯皇帝是不是一生只有一个妻子?我记得有野史说他只册封了一位皇后。”夏侯殷德有些出神望着前方。” “花令的确是个好姑娘,我欠她的本人自从看了七七,又忙不迭的去看《妾身六儿》 终于找到了传说中的真正结局
发贴请加前缀【陌上人如玉】楠竹成功篡位,但又放弃皇位坐以待毙被淳于反攻,最终携女主归隐格式有误请重发,此贴待删
为您推荐:
其他类似问题
奴儿七七的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。【视频】【评测】你以为77D是80D的降级版?信不信佳能打你的脸! - 十万瞬间【视频】【评测】你以为77D是80D的降级版?信不信佳能打你的脸!作者:十万瞬间 / 微信号:shiwanshunjian&发布日期:EOS系列的百位数机身从2003年的300D开始,以大约每年一更新的速度,到目前为止也到800D,也就是第11代的版本了。不过现在最有讨论性的还是77D。它们都搭载了Canon最新版的Dual Pixel AF技术,可以达到0.03秒对焦,同时还还拿Live View来测追焦。在操作的设计上对于初学摄影的朋友也非常好入门,体积也能够维持得相当轻巧,77D与800D在各方面来说都是相当优秀的机种。77D与800D可以说是几乎完全相同的产品,仅仅只有在操作上有细微的不同,但骨子里是一样的东西。过去在750D与760D这两个令人摸不着头绪的产品名称,的确一段时间搞不清楚到底760D是750D的后继机种,还是760D只是750D的勘误版。而原本我也以为Canon这个百位数微幅加强的版本会就此打住,没想到三月就出现了这台77D的谣传。说真的,在还没正式发表前我都不相信77D是真的,因为名称实在是太奇怪了,80D去年才推出,怎么可能还会有一台双位数机身出现,后来才知道它是760D的后继机种。原厂并没有对于77D的由来加以说明,我想77D的定位是排在800D之上、80D之下,所以才会不得以选择双位数机身,而千位数容易让人以为是更低阶的产品,个位数又有1DX、6D、7D等高阶器材。但以上都是猜测,各位又有什么想法呢?由于过去已经有总结过77D跟800D的比较,早总结上觉得已经够了,因为77D跟800D在机身内部几乎是完全一样的东西,只有外观与部分操作有相当细微的差别。我认为800D与77D固然会是初阶消费者会考虑的两台相机,但他们价格上不过就是差700元左右。真正让会让消费者苦恼的,应该是77D与80D的选择。所以这篇文章会把重点功能放在77D与80D的外观与重点功能比较。介绍的部分就以77D为主。77D与80D都是以18-135mm f/3.5-5.6 IS USM镜头为测试。与70D的套机18-135mm STM板不同的地方在于,USM版本的是Nano USM,对焦速度会明显地比追求流畅对焦的STM马达快许多,个人也强烈推荐USM版的18-135mm,对焦速度是一等一的快,一点都不输L镜等级的镜头。两台相机都是搭载APS-C尺寸2420万画素感光元件,但77D/800D使用的影像处理器是最新的Digic 7,而80D使用Digic 6。两台相机在快门声上的差异:个人很喜欢77D/800D机身侧面的隐藏式连接埠设计,不注意看还真的会以为侧面什么都没有。77D与80D都还是单卡槽,要一直到7D2的等级才会有双记忆卡插槽的设计。前段时间发布的Nikon D7500也是从原本D7200的双卡槽调整成单卡槽设计,现在D7500可以对上80D、7D2则可以正面对决D500了。77D在整体的造型设计上还是比较流线、时尚一点。很喜欢机背速控转盘使用同心圆亮面的设计,让转盘成为机背的一个亮点。77D具备与80D或同级以上机种的速控转盘。如果要说外面的那一圈,80D比较好转,虽然相较之下不是很好看,但旋转的刻度非常明确。而77D的速控转盘比较扁平,每一格的移动比较不明确,但钻石般的切面真的好看很多。再者,77D的速控转盘同时也是四向按键,这个设计就比80D中间的四向键好按许多。如果要我选的话,我还是比较喜欢77D的设计。想不通77D关于录像键的设计:开机/录像的操作按键的顺序是OFF/ON/录像。但很多时候开机就是会不小心推过头转到录像去,虽然每一格都有非常明显的阻力,但阻力又没有大到在任何情况下都能准确的推到ON的位置。比较常见的情况是轻轻推,推不动、稍微用点力就会直接推到录像键。很多时候是不小心推就直接到录像,只是想拍照而已,结果却浪费了许多时间,从反光镜翻起来准备录像、然后再回到ON把反光镜翻下来,其实已经浪费了不少时间。目前拥有这个设计的只有两台,一是前一代的760D、再来就是77D。其实百位数机身从650D开始就是类似的设计,不过它们是做在机顶,用拇指去推动,由下往上分别是OFF/ON/录影,不过就使用经验,在百位数机身鲜少发生过不小心推到录像的状况。翻转屏已逐渐成为主流。77D/800D/80D皆有。Canon的翻转屏最高也只到80D。机顶模式转盘,左边是80D,右边是77D。注意80D是没有那些运动/小花/风景/人像等模式的,因为那些模式都是设计给初学者专用,80D定位在进阶使用机种,摄影者自己会知道该使用何种曝光模式与设定。左边为80D,右边为77D。从机顶来看,77D与80D也有许多不同的地方。最明显的那个小型化、承袭自760D的机顶萤幕,还有较简化的机顶功能按钮,例如77D就不见对焦、连拍与测光模式按键,这些的部份功能都被放到机背的速控转盘的四向按键中。我们来看看77D与80D肩屏的差异:两者显示的内容是差不多的,80D就是多了上面对焦、连拍与测光模式。但很令人欣慰的是测光并没有被拿掉。由于77D机身体积与800D几乎完全一样的关系,77D自然需要采用更小的电池。但在续航力上并没有明显的折扣,如果完全使用光学观景窗拍摄的话,77D的续航力为820张,80D为960张。以握持感来说,80D由于握把处较厚的关系,在拇指以外的二到三指节都能有很好的包覆感,77D在这里基本上是悬空的。但两者的握把深度是相同的,即便是手稍大的也都能够让小指完整的覆盖到。77D与80D在规格上的比较:两者差异其实不大,甚至在这些重点规格上还有两项赢的地方。一是77D延伸ISO最高可以到51200。而Live View的对焦亮度检测,最低可达-2EV,对于在暗处拍摄是超棒的功能,80D也仅支援到0EV。为了让各位了解到800D/77D这个Live View到底打败了多少台Canon机身,我把目前所有Canon官网较新的产品列出来,就只看Live View最低对焦检测亮度这点:对焦检测亮度的意思,是相机在对焦时对于亮度的敏感度,只有在这个范围内的亮度能够对焦,在范围以外的,对焦系统会以为是一片全黑或全白,也就是完全没办法合焦,所以这个范围是越广越好,代表不管再多暗或者是多亮的地方都能够对焦。目前消费市场最低的检测亮度是-4EV,大概就是星星的亮度。对焦检测亮度是评价一台相机暗部对焦能力的重要指标,只是大多官方的宣传上很少见到这个资讯。当你在拍夜景的时候,别人的相机还在那里拉风箱拉个半天,77D/800D已经哔哔合焦了。检测亮度与拍照好不好看没关系,但与能不能成功拍到照片很有关系。对焦最低检测亮度可以说是内行人在对焦点上,除了数量以外最看重的东西了。功能介绍●新增引导选单
77D与800D在操作的逻辑上,会比过去的机种更偏向习惯手机拍照的摄影者。所以不论是77D或800D,都可以完全使用触控操作。虽然前面的产品也可以,但77D与800D的引导选单设计有明确的说明,更适合初学或对于拍照设定不熟悉的朋友。在操作上也能够以触控完成所有操作。整体的设计也较为活泼,过去都是黑底白字加上红色点缀,现在的选单变成白色底,并且有许多图示辅助,看起来活泼许多。●对焦能力77D/800D对于Live View的对焦能力非常有自信,在广告上大大的写下全球最快0.03秒自动对焦。不过我看了一下官网,比较的条件是所有配备APS-C尺寸影像感测器及于影像平面上进行相位差检测自动对焦的可换镜头数位相机,目前能够达到这几个条件的大概就只有Sony、Fujifilm两家而已。Sony A秒、Fujifilm X-T2为0.06秒。(比较的产品应该不超过10个)至于Nikon与Pentax我就不提了,这两家的多位数单反Live View对焦可以说是数十年如一日...有网友在讨论区提出77D与80D对焦速度的疑问,我觉得这两台相机对焦系统一样、套机镜头也一样,个人认为没有比较OVF对焦的必要。但800D/77D的Dual Pixel AF的演算法是最新版本的,所以理论上会比前面所有机种来得更快、更准。所以我们这里要看的是77D与80D在Live View对焦时的表现。由于77D的对焦系统与80是完全相同的规格,都是45点全十字,再加上现在新版的18-135mm用的是更快的Nano USM,对焦速度是真的很快,一点也不输许多L镜的表现。既然都说自己是世界最快了,那实在不得不拿来用高端相机的标准来检验。找来一辆以60km/h的速度行驶的汽车,避免使用流畅区域自动对焦,选择使用单点的原因,是因为流畅区域实在太大了(共9格),因为画面杂乱的缘故,我已经在现场试过,成功率会远低于单一点。对焦模式当然是AI SERVO并且开启连拍。请注意,通常用汽车来做追焦测试只有中端以上才使用。多位数单反的Live View居然可以用来追焦,这是真的吗?3年前多位数单反的Live View都还只能做单次对焦,而且失败率也相当高,现在都可以拿来追车子了。接下来我们要看准或是不准。总共取15张。我在这里特别拿来跟一般用观景窗的对焦方式做比较。不过因为两者会在连拍速度上会有差别。所以我是抓最后的位置往前数15张,各位应该可以发现第一张的图片会比较小,那是因为Live View花的时间比较多,所以车子会比较远一点。曝光时间都是1/1250s,不会有晃到的问题。用OVF拍摄的结果满让人意外,45点全十字型对焦点加上18-135mm的Nano USM,对焦成功率比想像中的高许多。至于为什么Live View在AI SERVO的连拍会降速,过去我一直把这件事情当作理所当然。后来一直到今年去Olympus总部跟工程师访谈的时候,他们就有提到Canon的Dual Pixel AF非常厉害,不但点与点之间没任何缝隙,对焦精度也非常高,但因为像素同时要负责感光与对焦,所以影像读出的时间要花2倍,这也就是为什么Live View时连续自动对焦连拍会降为4.5fps的原因。●各级感光度表现:与80D比较两台相机在ISO的表现相较之下几乎没有差别。但77D还多了ISO51200可用。●机身电子防手震
电子防手震分成两级:「启用」与「已提升(英文版叫做Enhanced,感谢中文翻译)」,Enhanced的效果较强,但画面裁切也会较多,原本镜头在18mm的位置大约会裁切成28mm左右。但令人有点困扰的是,使用电子防手震的前提,是镜头必须要有光学防手震,如果没有的话,机身虽然可以开启,但执行时相机会不断的闪烁电子防手震无效的图示。●使用心得与建议77D是800D的进阶版,而不是80D的降阶版,虽然官方只有说77D的定位是在80D与800D之间,但如果你仔细看选单内部的设定,其实很能够明显地了解77D是把800D往上推,而不是80D往下拉的产品。举一些例子:77D不能自定色温K值77D的HDR不能调整效果与张数,仅有SCN里的自动而已77D没有静音Live View拍摄77D永远都处在曝光模拟状态,没有关闭的方式C.Fn内部的曝光、自动对焦与操作设定77D有14项,80D却有26项上述只是随便举的六点,但各位仔细看看,其实这些功能对于初阶使用者来说真的不是很重要。例如不能自定色温是我在摄影棚内发现的一大问题;开启曝光模拟则容易让摄影师难以拍摄,例如微距摄影常会需要使用f/16以上的光圈,设1/160s与f/16等于是在Live View时什么都看不到(但77D可以让你在半按快门8秒钟内用最大光圈预览画面)。又例如C.Fn里面,80D能够调整追焦的灵敏度,而77D没办法调整。这些功能都算是在进阶的范畴内,对于刚入门的使用者来说真的有一点太多。Canon希望在800D/77D的这个范围内,是让喜欢摄影,或者觉得自己对于摄影有兴趣的使用者,800D/77D是能够把他们拉进摄影这个圈子的一块敲门砖,等到把这个层级的产品摸熟了,上面还有80D、7DII或者是6D这类更高阶的产品可以选择。那我该选77D还是80D?两者单机身价差两千多,的确是值得好好考虑。在的这两年间,Dual Pixel AF是70D的杀手锏,Canon就只有70D这个产品有而已,所以在800D/80D还没出现时,Canon的两位数单反我会极力推荐70D,因为就只有它有双像素对焦。但现在Canon是全系列EOS系统都要装上双像素对焦。而且现在的77D/800D是Canon所有产品中最新的Dual Pixel AF系统,加上有肩屏与速控转盘,其实对于初学者或进阶者来说都已经相当足够,除非是摄影者有意朝特定的摄影领域继续钻研,例如棚拍,或者是运动摄影等,对于机身功能有特定的要求。或者是想要有更快的操作与更细致的设定,我才会建议消费者选择80D。在操作上77D跟80D也不会真的差很多,差很多的在800D跟80D才是,差一个速控转盘与肩屏就有非常明显的差距。 个人认为77D用完要往上升级的话,7D2才会有明显的感受,除了对焦系统与连拍大幅升级,机背有独立调整对焦点的摇杆。几乎是100%全部加强。7D2可以说是APS-C版的1DX了。(咱们就先不要讨论到那一块好了)。虽然使用的时间不长,但77D对于不熟悉摄影的使用者来说,是一个相当好的入门产品,它包办了从最入门到进阶入门这个领域的摄影者,也把初阶消费者的使用时间拉得更长,我不需要为了多一个速控转盘与肩屏而花大钱?,对于消费者来说是个利多。而且新的引导式选单操作起来也比过去更容易,搭配套机镜头对焦速度也有非常好的表现,所以相当推荐77D给大家。(最后,我觉得77D与800D的差距实在太小了,我猜未来有可能这两个系列会直接合并,然后更低阶的产品由100D或1200D系列补上,可以过个几年再来看看这个预言会不会成真。)77D/800D表现不错的地方:◎翻转屏◎Live View的对焦点检测亮度是从-2EV起跳,在所有EOS系统中仅输1DXII与5D4◎Live View对焦速度是所有数位单反厂牌中最快的◎操作与80D系列相似◎新的引导选单让新手更好入门◎搭配18-135mm USM版本对焦速度相当快。来源:mobile01长按关注解锁更多精彩内幕十万瞬间微信号 : shiwanshunjian新浪微博:@十万瞬间相关文章猜你喜欢历史学考研和就业垒晟咨询汽车抵押现代诗刊法苑杂说每日评币#统计代码Android逆向之旅
我的图书馆
Android逆向之旅
Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码)
&& 来源:jiangwei的专栏&&
一、前言今天我们继续来看破解apk的相关知识,在前一篇:我们今天主要来看如何使用IDA来调试Android中的native源码,因为现在一些app,为了安全或者效率问题,会把一些重要的功能放到native层,那么这样一来,我们前篇说到的Eclipse调试smali源码就显得很无力了,因为核心的都在native层,Android中一般native层使用的是so库文件,所以我们这篇就来介绍如何调试so文件的内容,从而让我们破解成功率达到更高的一层。二、知识准备我们在介绍如何调试so文件的时候,先来看一下准备知识:第一、IDA工具的使用早在之前的一篇文章:中使用IDA工具静态分析so文件,通过分析arm指令,来获取破解信息,比如打印的log信息,来破解apk的,在那时候我们就已经介绍了如何使用IDA工具:这里有多个窗口,也有多个视图,用到最多的就是:1、Function Window对应的so函数区域:这里我们可以使用ctrl+f进行函数的搜索2、IDA View对应的so中代码指令视图:这里我们可以查看具体函数对应的arm指令代码3、Hex View对应的so的十六进制数据视图:我们可以查看arm指令对应的数据等当然在IDA中我们还需要知道一些常用的快捷键:1、强大的F5快捷键可以将arm指令转化成可读的C语言,帮助分析首先选中需要翻译成C语言的函数,然后按下F5:看到了,立马感觉清爽多了,这些代码看起来应该会好点了。下面我们还需要做一步,就是还原JNI函数方法名一般JNI函数方法名首先是一个指针加上一个数字,比如v3+676。然后将这个地址作为一个方法指针进行方法调用,并且第一个参数就是指针自己,比如(v3+676)(v3…)。这实际上就是我们在JNI里经常用到的JNIEnv方法。因为Ida并不会自动的对这些方法进行识别,所以当我们对so文件进行调试的时候经常会见到却搞不清楚这个函数究竟在干什么,因为这个函数实在是太抽象了。解决方法非常简单,只需要对JNIEnv指针做一个类型转换即可。比如说上面提到a1和v4指针:我们可以选中a1变量,然后按一下y键:然后将类型声明为:JNIEnv*。确定之后再来看:修改之后,是不是瞬间清晰了很多?另外有人( 貌似是看雪论坛上的)还总结了所有JNIEnv方法对应的数字,地址以及方法声明:2、Shirt+F12快捷键,速度打开so中所有的字符串内容窗口有时候,字符串是一个非常重要的信息,特别是对于破解的时候,可能就是密码,或者是密码库信息。3、Ctrl+S快捷键,有两个用途,在正常打开so文件的IDA View视图的时候,可以查看so对应的Segement信息可以快速得到,一个段的开始位置和结束位置,不过这个位置是相对位置,不是so映射到内存之后的位置,关于so中的段信息,不了解的同学可以参看这篇文章:这篇文章介绍的很很清楚了,这里就不在作介绍了。当在调试页面的时候,ctrl+s可以快速定位到我们想要调试的so文件映射到内存的地址:因为一般一个程序,肯定会包含多个so文件的,比如系统的so就有好多的,一般都是在/system/lib下面,当然也有我们自己的so,这里我们看到这里的开始位置和结束位置就是这个so文件映射到内存中:这里我们可以使用cat命令查看一个进程的内存映射信息:cat /proc/[pid]/maps我们看到映射信息中有多so文件,其实这个不是多个so文件,而是so文件中对应的不同Segement信息被映射到内存中的,一般是代码段,数据段等,因为我们需要调试代码,所以我们只关心代码段,代码段有一个特点就是具有执行权限x,所以我们只需要找到权限中有x的那段数据即可。4、G快捷键:在IDA调试页面的时候,我们可以使用S键快速跳转到指定的内存位置这里的跳转地址,是可以算出来的,比如我现在想跳转到A函数,然后下断点,那么我们可以使用上面说到的ctrl+s查找到so文件的内存开始的基地址,然后再用IDA View中查看A函数对应的相对地址,相加就是绝对地址,然后跳转到即可,比如这里的:Java_cn_wjdiankong_encryptdemo_MainActivity_isEquals 函数的IDA View中的相对地址(也就是so文件的地址):E9C上面看到so文件映射到内存的基地址:74FE4000那么跳转地址就是:74FEFE4E9C注意:一般这里的基地址只要程序没有退出,在运行中,那么他的值就不会变,因为程序的数据已经加载到内存中了,基地址不会变的,除非程序退出,又重新运行把数据加载内存中了,同时相对地址是永远不会变的,只有在修改so文件的时候,文件的大小改变了,可能相对地址会改变,其他情况下不会改变,相对地址就是数据在整个so文件中的位置。这里我们可以看到函数映射到内存中的绝对地址了。注意:有时候我们发现跳转到指定位置之后,看到的全是DCB数据,这时候我们选择函数地址,点击P键就可以看到arm指令源码了:5、调试快捷键:F8单步调试,F7单步进入调试上面找到函数地址之后,我们可以下断点了,下断点很简单,点击签名的绿色圈点,变成红色条目即可,然后我们可以点击F9快捷键,或者是点击运行按钮,即可运行程序:其中还有暂停和结束按钮。我们运行之后,然后在点击so的native函数,触发断点逻辑:这时候,我们看到进入调试界面,点击F8可以单步调试,看到有一个PC指示器,其实在arm中PC是一个特殊的寄存器,用来存储当前指令的地址,这个下面会介绍到。好了到这里,我们就大致说了一下关于IDA在调试so文件的时候,需要用到的快捷键:1、Shift+F12快速查看so文件中包含的字符串信息2、F5快捷键可以将arm指令转化成可读的C代码,这里同时可以使用Y键,修改JNIEnv的函数方法名3、Ctrl+S有两个用途,在IDA View页面中可以查看so文件的所有段信息,在调试页面可以查看程序所有so文件映射到内存的基地址4、G键可以在调试界面,快速跳转到指定的绝对地址,进行下断点调试,这里如果跳转到目的地址之后,发现是DCB数据的话,可以在使用P键,进行转化即可,关于DCB数据,下面会介绍的。5、F7键可以单步进入调试,F8键可以单步调试第二、常用的ARM指令集知识我们在上面看到IDA打开so之后,看到的是纯种的汇编指令代码,所以这就要求我们必须会看懂汇编代码,就类似于我们在调试Java层代码的时候一样,必须会smali语法,庆幸的是,这两种语法都不是很复杂,所以我们知道一些大体的语法和指令就可以了,下面我们来看看arm指令中的寻址方式,寄存器,常用指令,看完这三个知识点,我们就会对arm指令有一个大体的了解,对于看arm指令代码也是有一个大体的认知了。1、arm指令中的寻址方式1&. 立即数寻址也叫立即寻址,是一种特殊的寻址方式,操作数本身包含在指令中,只要取出指令也就取到了操作数。这个操作数叫做立即数,对应的寻址方式叫做立即寻址。例如:MOV R0,#64 ;R0 ← 642&. 寄存器寻址寄存器寻址就是利用寄存器中的数值作为操作数,也称为寄存器直接寻址。例如:ADD R0,R1, R2 ;R0 ← R1 + R23&. 寄存器间接寻址寄存器间接寻址就是把寄存器中的值作为地址,再通过这个地址去取得操作数,操作数本身存放在存储器中。例如:LDR R0,[R1] ;R0 ←[R1]4&. 寄存器偏移寻址这是ARM指令集特有的寻址方式,它是在寄存器寻址得到操作数后再进行移位操作,得到最终的操作数。例如:MOV R0,R2,LSL #3 ;R0 ← R2 * 8 ,R2的值左移3位,结果赋给R0。5&. 寄存器基址变址寻址寄存器基址变址寻址又称为基址变址寻址,它是在寄存器间接寻址的基础上扩展来的。它将寄存器(该寄存器一般称作基址寄存器)中的值与指令中给出的地址偏移量相加,从而得到一个地址,通过这个地址取得操作数。例如:LDR R0,[R1,#4] ;R0 ←[R1 + 4],将R1的内容加上4形成操作数的地址,取得的操作数存入寄存器R0中。6&. 多寄存器寻址这种寻址方式可以一次完成多个寄存器值的传送。例如:LDMIA R0,{R1,R2,R3,R4} ;R1←[R0],R2←[R0+4],R3←[R0+8],R4←[R0+12]7&. 堆栈寻址堆栈是一种数据结构,按先进后出(First In Last Out,FILO)的方式工作,使用堆栈指针(Stack Pointer, SP)指示当前的操作位置,堆栈指针总是指向栈顶。堆栈寻址举例如下:STMFD SP!,{R1-R7, LR} ;将R1-R7, LR压入堆栈。满递减堆栈。LDMED SP!,{R1-R7, LR} ;将堆栈中的数据取回到R1-R7, LR寄存器。空递减堆栈。2、ARM中的寄存器R0-R3:用于函数参数及返回值的传递R4-R6, R8, R10-R11:没有特殊规定,就是普通的通用寄存器R7:栈帧指针(Frame Pointer).指向前一个保存的栈帧(stack frame)和链接寄存器(link register, lr)在栈上的地址。R9:操作系统保留R12:又叫IP(intra-procedure scratch )R13:又叫SP(stack pointer),是栈顶指针R14:又叫LR(link register),存放函数的返回地址。R15:又叫PC(program counter),指向当前指令地址。3、ARM中的常用指令含义ADD 加指令SUB 减指令STR 把寄存器内容存到栈上去LDR 把栈上内容载入一寄存器中.W 是一个可选的指令宽度说明符。它不会影响为此指令的行为,它只是确保生成 32 位指令。Infocenter.arm.com的详细信息BL 执行函数调用,并把使lr指向调用者(caller)的下一条指令,即函数的返回地址BLX 同上,但是在ARM和thumb指令集间切换。CMP 指令进行比较两个操作数的大小4、ARM指令简单代码段分析C代码:#include int func(int a, int b, int c, int d, int e, int f){ int g = a + b + c + d + e +}对应的ARM指令:add r0, r1 将参数a和参数b相加再把结果赋值给r0ldr.w r12, [sp] 把最的一个参数f从栈上装载到r12寄存器add r0, r2 把参数c累加到r0上ldr.w r9, [sp, #4] 把参数e从栈上装载到r9寄存器add r0, r3 累加d累加到r0add r0, r12 累加参数f到r0add r0, r9 累加参数e到r0三、构造so案例好了,关于ARM指令的相关知识,就介绍这么多了,不过我们在调试分析的时候,肯定不能做到全部的了解,因为本身ARM指令语法就比较复杂,不过幸好大学学习了汇编语言,所以稍微能看懂点,如果不懂汇编的同学那就可能需要补习一下了,因为我们在使用IDA分析so文件的时候,不会汇编的话,那是肯定行不通的,所以我们必须要看懂汇编代码的,如果遇到特殊指令不了解的同学,可以网上搜一下即可。上面我们的准备知识做完了,一个是IDA工具的时候,一个是ARM指令的了解,下面我们就来开始操刀了,为了方便开始,我们先自己写一个简单的Android native层代码,然后进行IDA进行分析即可。这里可以使用AndroidStudio中进行新建一个简单工程,然后创建JNI即可:这里顺便简单说一下AndroidStudio中如何进行NDK的开发吧:第一步:在工程中新建jni目录第二步:使用javah生成native的头文件注意:javah执行的目录,必须是类包名路径的最上层,然后执行:javah 类全名注意没有后缀名java哦第三步:配置项目的NDK目录选择模块的设置选线:Open Module Settings:设置NDK目录即可第四步:copy头文件到jni目录下,然后配置gradle中的ndk选项这里只需要设置编译之后的模块名,就是so文件的名称,需要产生那几个平台下的so文件,还有就是需要用到的lib库,这里我们看到我们用到了Android中打印log的库文件。第五步:编译运行,在build目录下生成指定的so文件,copy到工程的libs目录下即可好了,到这里我们就快速的在AndroidStudio中新建了一个Native项目,这里关于native项目的代码不想解释太多,就是Java层传递了用户输入的密码,然后native做了校验过程,把校验结果返回到Java层即可:具体的校验过程这里不再解释了。我们运行项目之后,得到apk文件,那么下面我们就开始我们的破解旅程了四、开始破解so文件开始破解我们编译之后的apk文件第一、首先我们可以使用最简单的压缩软件,打开apk文件,然后解压出他的so文件我们得到libencrypt.so文件之后,使用IDA打开它:我们知道一般so中的函数方法名都是:Java_类名_方法名那么这里我们直接搜:Java关键字即可,或者使用jd-gui工具找到指定的native方法双击,即可在右边的IDA View页面中看到Java_cn_wjdiankong_encryptdemo_MainActivity_isEquals 函数的指令代码:我们可以简单的分析一下这段指令代码:1&、PUSH {r3-r7,lr} 是保存r3,r4,r5,r6,r7,lr 的值到内存的栈中,那么最后当执行完某操作后,你想返回到lr指向的地方执行,当然要给pc了,因为pc保留下一条CPU即将执行的指令,只有给了pc,下一条指令才会执行到lr指向的地方pc:程序寄存器,保留下一条CPU即将执行的指令lr: 连接返回寄存器,保留函数返回后,下一条应执行的指令这个和函数最后面的POP {r3-r7,pc}是相对应的。2&、然后是调用了strlen,malloc,strcpy等系统函数,在每次使用BLX和BL指令调用这些函数的时候,我们都发现了一个规律:就是在调用他们之前一般都是由MOV指令,用来传递参数值的,比如这里的R5里面存储的就是strlen函数的参数,R0就是is_number函数的参数,所以我们这样分析之后,在后面的动态调试的过程中可以得到函数的入口参数值,这样就能得到一些重要信息3&、在每次调用有返回值的函数之后的命令,一般都是比较指令,比如CMP,CBZ,或者是strcmp等,这里是我们破解的突破点,因为一般加密再怎么牛逼,最后比较的参数肯定是正确的密码(或者是正确的加密之后的密码)和我们输入的密码(或者是加密之后的输入密码),我们在这里就可以得到正确密码,或者是加密之后的密码:到这里,我们就分析完了native层的密码比较函数:Java_cn_wjdiankong_encryptdemo_MainActivity_isEquals如果觉得上面的ARM指令看的吃力,可以使用F5键,查看他的C语言代码:我们这里看到其实有两个函数是核心点:1&is_number函数,这个函数我们看名字应该猜到是判断是不是数字,我们可以使用F5键,查看他对应的C语言代码:这里简单一看,主要是看return语句和if判断语句,看到这里有一个循环,然后获取_BYTE*这里地址的值,并且自增加一,然后存到v2中,如果v3为"\0'的话,就结束循环,然后做一次判断,就是v2-48是否大于9,那么这里我们知道48对应的是ASCII中的数字0,所以这里可以确定的是就是:用一个循环遍历_BYTE*这里存的字符串是否为数字串。2&get_encrypt_str函数,这个函数我们看到名字可以猜测,他是获取我们输入的密码加密之后的值,再次使用F5快捷键查看:这里我们看到,首先是一个if语句,用来判断传递的参数是否为NULL,如果是的话,直接返回,不是的话,使用strlen函数获取字符串的长度保存到v2中,然后使用malloc申请一块堆内存,首指针保存到result,大小是v2+1也就是传递进来的字符串长度+1,然后就开始进入循环,首指针result,赋值给i指针,开始循环,v3是通过v1-1获取到的,就是函数传递进来字符串的地址,那么v6就是获取传递进来字符串的字符值,然后减去48,赋值给v7,这里我们可以猜到了,这里想做字符转化,把char转化成int类型,继续往下看,如果v6==48的话,v7=1,也就是说这里如果遇到字符"0',就赋值1,在往下看,看到我们上面得到的v7值,被用来取key_src数组中的值,那么这里我们双击key_src变量,就跳转到了他的值地方,果不其然,这里保存了一个字符数组,看到他的长度正好是18,那么这里我们应该明白了,这里通过传递进来的字符串,循环遍历字符串,获取字符,然后转化成数字,在倒序获取key_src中的字符,保存到result中。然后返回。好了,到这里我们就分析完了这两个重要的函数的功能,一个是判断输入的内容是否为数字字符串,一个是通过输入的内容获取密码内容,然后和正确的加密密码:ssBCqpBssP 作比较。第二、开始使用IDA进行调试设置那么下面我们就用动态调试来跟踪传入的字符串值,和加密之后的值,这里我们看到没有打印log的函数,所以很难知道具体的参数和寄存器的值,所以这里需要开始调试,得知每个函数执行之后的寄存器的值,我们在用IDA进行调试so的时候,需要以下准备步骤:1、在IDA安装目录下获取android_server命令文件在IDA安装目录\dbgsrv\android_server,这个文件是干嘛的呢?他怎么运行呢?下面来介绍一下:我们是否还记得之前一篇文章: 这篇文章中我们介绍了Android中的调试原理,其实是使用gdb和gdbserver来做到的,gdb和gdbserver在调试的时候,必须注入到被调试的程序进程中,但是非root设备的话,注入别的进程中只能借助于run-as这个命令了,所以我们知道,如果要调试一个应用进程的话,必须要注入他内部,那么IDA调试so也是这个原理,他需要注入(Attach附加)进程,才能进行调试,但是IDA没有自己弄了一个类似于gdbserver这样的工具,那就是android_server了,所以他需要运行在设备中,保证和PC端的IDA进行通信,比如获取设备的进程信息,具体进程的so内存地址,调试信息等。所以我们把android_server保存到设备的/data目录下,修改一下他的运行权限,然后必须在root环境下运行,因为他要做注入进程操作,必须要root。注意:这里把他放在了/data目录下,然后./android_server运行,这里提示了IDA Android 32-bit,所以后面我们在打开IDA的时候一定要是32位的IDA,不是64位的,不然保存,IDA在安装之后都是有两个可执行的程序,一个是32位,一个是64位的,如果没打开正确会报这样的错误:同样还有一类问题:error: only position independent executables (PIE) are supported这个主要是Android5.0以上的编译选项默认开启了pie,在5.0以下编译的原生应用不能运行,有两种解决办法,一种是用Android5.0以下的手机进行操作,还有一种就是用IDA6.6+版本即可。然后我们再看,这里开始监听了设备的23946端口,那么如果要想让IDA和这个android_server进行通信,那么必须让PC端的IDA也连上这个端口,那么这时候就需要借助于adb的一个命令了:adb forward tcp:远端设备端口号(进行调试程序端) tcp:本地设备端口(被调试程序端)那么这里,我们就可以把android_server端口转发出去:然后这时候,我们只要在PC端使用IDA连接上23946这个端口就可以了,这里面有人好奇了,为什么远程端的端口号也是23946,因为后面我们在使用IDA进行连接的时候,发现IDA他把这个端口设置死了,就是23946,所以我们没办法自定义这个端口了。我们可以使用netstat命令查看端口23946的使用情况,看到是ida在使用这个端口2、上面就准备好了android_server,运行成功,下面就来用IDA进行尝试连接,获取信息,进行进程附加注入我们这时候需要在打开一个IDA,之前打开一个IDA是用来分析so文件的,一般用于静态分析,我们要调试so的话,需要在打开一个IDA来进行,所以这里一般都是需要打开两个IDA,也叫作双开IDA操作。动静结合策略。这里记得选择go这个选项,就是不需要打开so文件了,进入是一个空白页:我们选择Debugger选项,选择Attach,看到有很多debugger,所以说IDA工具真的很强大,做到很多debugger的兼容,可以调试很多平台下的程序。这里我们选择Android debugger:这里看到,端口是写死的:23946,不能进行修改,所以上面的adb forward进行端口转发的时候必须是23946。这里PC本地机就是调试端,所以host就是本机的ip地址:127.0.0.1,点击确定:这里可以看到设备中所有的进程信息就列举出来的,其实都是android_server干的事,获取设备进程信息传递给IDA进行展示。注意:如果我们当初没有用root身份去运行android_server:这里就会IDA是不会列举出设备的进程信息:还有一个注意的地方,就是IDA和android_server一定要保持一致。我们这里可以ctrl+F搜索我们需要调试的进程,当然这里我们必须运行起来我们需要调试的进程,不然也是找不到这个进程的双击进程,即可进入调试页面:这里为什么会断在libc.so中呢?android系统中libc是c层中最基本的函数库,libc中封装了io、文件、socket等基本系统调用。所有上层的调用都需要经过libc封装层。所以libc.so是最基本的,所以会断在这里,而且我们还需要知道一些常用的系统so,比如linker:我们知道,这个linker是用于加载so文件的模块,所以后面我们在分析如何在.init_array处下断点还有一个就是libdvm.so文件,他包含了DVM中所有的底层加载dex的一些方法:我们在后面动态调试需要dump出加密之后的dex文件,就需要调试这个so文件了。3、找到函数地址,下断点,开始调试我们使用Ctrl+S找到需要调试so的基地址:74FE4000然后通过另外一个IDA打开so文件,查看函数的相对地址:E9C那么得到了函数的绝对地址就是:74FE4E9C,使用G键快速跳转到这个绝对地址:跳转到指定地址之后,开始下断点,点击最左边的绿色圆点即可下断点:然后点击左上角的绿色按钮,运行,也可以使用F9键运行程序:我们点击程序中的按钮:触发native函数的运行:看到了,进入调试阶段了,这时候,我们可以使用F8进行单步调试,F7进行单步进入调试:我们点击F8进行单步调试,达到is_number函数调用出,看到R0是出入的参数值,我们可以查看R0寄存器的内容,然后看到是123456,这个就是Java层传入的密码字符串,接着往下走:这里把is_number函数返回值保存到R0寄存中,然后调用CBZ指令,判断是否为0,如果为0就跳转到locret_74FE4EEC处,查看R0寄存器的值不是0,继续往下走:看到了get_encrypt_str函数的调用,函数的返回值保存在R1寄存器中,查看内容:zytyrTRA*B了,那么看到,上层传递的:123456=》zytyrTRA*B了,前面我们静态分析了get_encrypt_str函数的逻辑,继续往下看:看到了,这里把上面得到的字符串和ssBCqpBssP作比较,那么这里ssBCqpBssP就是正确的加密密码了,那么我们现在的资源是:正确的加密密码:ssBCqpBssP,加密密钥库:zytyrTRA*BniqCPpVs,加密逻辑get_encrypt_str那么我们可以写一个逆向的加密方法,去解析正确的加密密码得到值即可,这里为了给大家一个破解的机会,这里就不公布正确答案了,这个apk我随后会上传,手痒的同学可以尝试破解一下。加密apk下载地址:第三、总结IDA调试的流程到这里,我们就分析了如何破解apk的流程,下面来总结一下:1、我们通过解压apk文件,得到对应的so文件,然后使用IDA工具打开so,找到指定的native层函数2、通过IDA中的一些快捷键:F5,Ctrl+S,Y等键来静态分析函数的arm指令,大致了解函数的执行流程3、再次打开一个IDA来进行调试so1&将IDA目录中的android_server拷贝到设备的指定目录下,修改android_server的运行权限,用Root身份运行android_server2&使用adb forward进行端口转发,让远程调试端IDA可以连接到被调试端3&使用IDA连接上转发的端口,查看设备的所有进程,找到我们需要调试的进程。4&通过打开so文件,找到需要调试的函数的相对地址,然后在调试页面使用Ctrl+S找到so文件的基地址,相加之后得到绝对地址,使用G键,跳转到函数的地址处,下好断点。点击运行或者F9键。5&触发native层的函数,使用F8和F7进行单步调试,查看关键的寄存器中的值,比如函数的参数,和函数的返回值等信息总结就是:在调试so的时候,需要双开IDA,动静结合分析。五、使用IDA来解决反调试问题那么到这里我们就结束了我们这期的破解旅程了?答案是否定的,因为我们看到上面的例子其实是我自己先写了一个apk,目的就是为了给大家演示,如何使用IDA来进行动态调试so,那么下面我们还有一个操刀动手的案例,就是2014年,阿里安全挑战赛的第二题:AliCrackme_2:阿里真会制造氛围,还记得我们破解的第一题吗,这次看到了第二题,好吧,下面来看看破解流程吧:首先使用aapt命令查看他的AndroidManifest.xml文件,得到入口的Activity类:然后使用dex2jar和jd-gui查看他的源码类:com.yaotong.crackme.MainActivity:看到,他的判断,是securityCheck方法,是一个native层的,所以这时候我们去解压apk文件,获取他的so文件,使用IDA打开查看native函数的相对地址:11A8这里的ARM指令代码不在分析了,大家自行查看即可,我们直接进入调试即可:在打开一个IDA进行关联调试:选择对应的调试进程,然后确定:使用Ctrl+S键找到对应so文件的基地址:74EA9000和上面得到的相对地址相加得到绝对地址:74EA=74EAA1A8 使用G键直接跳到这个地址:下个断点,然后点击F9运行程序:擦,IDA退出调试页面了,我们再次进入调试页面,运行,还是退出调试页面了,好了,这下蛋疼了,没法调试了。这里其实是阿里做了反调试侦查,如果发现自己的程序被调试了,就直接退出程序,那么这里有问题了,为什么知道是反调试呢?这个主要还是看后续自己的破解经验了,没技术可言,还有一个就是阿里如何做到的反调试策略的,这里限于篇幅,只是简单介绍一下原理:前面说到,IDA是使用android_server在root环境下注入到被调试的进程中,那么这里用到一个技术就是Linux中的ptrace,关于这个这里也不解释了,大家可以自行的去搜一下ptrace的相关知识,那么Android中如果一个进程被另外一个进程ptrace了之后,在他的status文件中有一个字段:TracerPid 可以标识是被哪个进程trace了,我们可以使用命令查看我们的被调试的进行信息:status文件在:/proc/[pid]/status看到了,这里的进程被9187进程trace了,我们在用ps命令看看9187是哪个进程:果不其然,是我们的android_server进程,好了,我们知道原理了,也大致猜到了阿里在底层做了一个循环检测这个字段如果不为0,那么代表自己进程在被人trace,那么就直接停止退出程序,这个反检测技术用在很多安全防护的地方,也算是一个重要的知识点了。那么下面就来看看如何应对这个反调试?我们刚刚看到,只要一运行程序,就退出了调试界面,说明,这个循环检测程序执行的时机非常早,那么我们现在知道的最早的两个时机是:一个是.init_array,一个是JNI_OnLoad.init_array是一个so最先加载的一个段信息,时机最早,现在一般so解密操作都是在这里做的JNI_OnLoad是so被System.loadLibrary调用的时候执行,他的时机要早于哪些native方法执行,但是没有.init_array时机早那么知道了这两个时机,下面我们先来看看是不是在JNI_OnLoad函数中做的策略,所以我们需要先动态调试JNI_OnLoad函数我们既然知道了JNI_OnLoad函数的时机,如果阿里把检测函数放在这里的话,我们不能用之前的方式去调试了,因为之前的那种方式时机太晚了,只要运行就已经执行了JNI_OnLoad函数,所以就会退出调试页面,幸好这里IDA提供了在so文件load的时机,我们只需要在Debug Option中设置一下就可以了:在调试页面的Debugger 选择 Debugger Option选项:然后勾选Suspend on library load/unload即可这样设置之后,还是不行,因为我们程序已经开始运行,就在static代码块中加载so文件了,static的时机非常早,所以这时候,我们需要让程序停在加载so文件之前即可。那么我想到的就是添加代码waitForDebugger代码了,这个方法就是等待debug,我们还记得在之前的调试smali代码的时候,就是用这种方式让程序停在了启动出,然后等待我们去用jdb进行attach操作。那么这一次我们可以在System.loadLibrary方法之前加入waitForDebugger代码即可,但是这里我们不这么干了,还有一种更简单的方式就是用am命令,本身am命令可以启动一个程序,当然可以用debug方式启动:adb shell am start -D -n com.yaotong.crackme/.MainActivity这里一个重要参数就是-D,用debug方式启动运行完之后,设备是出于一个等待Debugger的状态:这时候,我们再次使用IDA进行进程的附加,然后进入调试页面,同时设置一下Debugger Option选项,然后定位到JNI_OnLoad函数的绝对地址。但是我们发现,这里没有RX权限的so文件,说明so文件没有加载到内存中,想一想还是对的,以为我们现在的程序是wait Debugger,也就是还没有走System.loadLibrary方法,so文件当然没有加载到内存中,所以我们需要让我们程序跑起来,这时候我们可以使用jdb命令去attach等待的程序,命令如下:jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700其实这条命令的功能类似于,我们前一篇说到用Eclipse调试smali源码的时候,在Eclipse中设置远程调试工程一样,选择Attach方式,调试机的ip地址和端口,还记得8700端口是默认的端口,但是我们运行这个命令之后,出现了一个错误:擦,无法连接到目标的VM,那么这种问题大部分都出现在被调试程序不可调试,我们可以查看apk的android:debuggable属性:果不其然,这里没有debug属性,所以这个apk是不可以调试的,所以我们需要添加这个属性,然后在回编译即可:回编译:java -jar apktool.jar b -d out -o debug.apk签名apk:java -jar .\sign\signapk.jar .\sign\testkey.x509.pem .\sign\testkey.pk8 debug.apk debug.sig.apk然后在次安装,使用am 命令启动:第一步:运行:adb shell am start -D -n com.yaotong.crackme/.MainActivity出现Debugger的等待状态第二步:启动IDA 进行目标进程的Attach操作第三步:运行:jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700第三步:设置Debugger Option选项第四步:点击IDA运行按钮,或者F9快捷键,运行看到了,这次jdb成功的attach住了,debug消失,正常运行了,但是同时弹出了一个选择提示:这时候,不用管它,全部选择取消按钮,然后就运行到了linker模块了:这时候,说明so已经加载进来了,我们再去获取JNI_OnLoad函数的绝对地址Ctrl+S查找到了基地址:用静态方式IDA打开so查看相对地址:1B9C相加得到绝对地址:B9C=7515BB9C,然后点击S键,跳转:跳转到指定的函数位置:这时候再次点击运行,进入了JNI_OnLoad处的断点:下面咋们就开始单步调试了,但是当我们每次到达BLX R7这条指令执行完之后,就JNI_OnLoad就退出了:经过好几次尝试都是一样的结果,所以我们发现这个地方有问题,可能就是反调试的地方了我们再次进入调试,看见BLX跳转的地方R7寄存器中是pthread_create函数,这个是Linux中新建一个线程的方法所以阿里的反调试就在这里开启一个线程进行轮训操作,去读取/proc/[pid]/status文件中的TrackerPid字段值,如果发现不为0,就表示有人在调试本应用,在JNI_OnLoad中直接退出。其实这里可以再详细进入查看具体代码实现的,但是这里限于篇幅问题,不详细解释了,后续在写一篇文章我们自己可以实现这种反调试机制的。本文的重点是能够动态调试即可。那么问题找到了,我们现在怎么操作呢?其实很简单,我们只要把BLX R7这段指令干掉即可,如果是smali代码的话,我们可以直接删除这行代码即可,但是so文件不一样,他是汇编指令,如果直接删除这条指令的话,文件会发生错乱,因为本身so文件就有固定的格式,比如很多Segement的内容,每个Segement的偏移值也是有保存的,如果这样去删除会影响这些偏移值,会破坏so文件格式,导致so加载出错的,所以这里我们不能手动的去删除这条指令,我们还有另外一种方法,就是把这条指令变成空指令,在汇编语言中,nop指令就是一个空指令,他什么都不干,所以这里我们直接改一下指令即可,arm中对应的nop指令是:00 00 00 00那么我们看到BLX R7对应的指令位置为:1C58查看他的Hex内容是:37 FF 2F E1我们可以使用一些二进制文件软件进行内容的修改,这里使用010Editor工具进行修改:这里直接修改成00 00 00 00:这时候,保存修改之后的so文件,我们再次使用IDA进行打开查看:哈哈,指令被修改成了:ANDEQ R0,R0,R0了那么修改了之后,我们在替换原来的so文件,再次重新回编译,签名安装,再次按照之前的逻辑给主要的加密函数下断点,这里不需要在给JNI_OnLoad函数下断点了,因为我们已经修改了反调试功能了,所以这里我们只需要按照这么简单几步即可:第一步:启动程序第二步:使用IDA进行进程的attach第三步:找到Java_com_yaotong_crackme_MainActivity_securityCheck函数的绝对地址第四步:打上断点,点击运行,进行单步调试看到了吧,这里我们可以单步调试进来了啦啦,说明我们修改反调试指令成功了。下面就继续F8单步调试:调试到这里,发现一个问题,就是CMP指令之后,BNE 指令就开始跳转到loc_74FAF2D0处了,那么我们就可以猜到了,CMP指令比较的应该就是我们输入的密码和正确的密码,我们再次从新调试,看看R3和R1寄存器的值看到了这里的R3寄存器的值就是用寄存器寻址方式,赋值字符串的,这里R2寄存器就是存放字符串的地址,我们看到的内容是aiyou...但是这里肯定不是全部字符串,因为我们没看到字符串的结束符:"\0',我们点击R2寄存器,进入查看完整内容:这里是全部内容:aiyou,bucuoo我们继续查看R1寄存器的内容:这里也是同样用寄存器寻址,R0寄存器存储的是R1中字符串的地址,我们看到这里的字符串内容是:jiangwei这个就是我输入的内容,那么这里就可以豁然开朗了,密码是上面的:aiyou,bucuoo我们再次输入这个密码:哈哈哈,破解成功啦啦~~手痒的同学可以下载项目来玩玩~~项目下载:六、技术总结到这里我们算是讲解完了如何使用IDA来调试so代码,从而破解apk的知识了,因为这里IDA工具比较复杂,所以这篇文章篇幅有点长,所以同学们可以多看几遍,就差不多了。下面我们来整理一下这篇文章中涉及到的知识点吧:第一、IDA中的常用快捷键使用1、Shift+F12可以快速查看so中的常量字符串内容,有时候,字符串内容是一个很大的突破点2、使用强大的F5键,可以查看arm汇编指令对应的C语言代码,同时可以使用Y键,进行JNIEnv*方法的还原3、使用Ctrl+S键,可以在IDA View页面中查看so的所有段信息,在调试页面可以查找对应so文件映射到内存的基地址,这里我们还可以使用G键,进行地址的跳转4、使用F8进行单步调试,F7进行单步跳入调试,同时可以使用F9运行程序第二、ARM汇编指令相关知识1、了解了几种寻址方式,有利于我们简单的读懂arm汇编指令代码2、了解了arm中的几种寄存器的作用,特别是PC寄存器3、了解了arm中常用的指令,比如:MOV,ADD,SUB,LDR,STR,CMP,CBZ,BL,BLX第三、使用IDA进行调试so的步骤,这里分两种情况1、IDA调试无反调试的so代码步骤:1》把IDA安装目录中的android_server拷贝到设备的指定目录中,修改android_server的权限,并且用root方式运行起来,监听23946端口2》使用adb forward命令进行端口的转发,将设备被调试端的端口转发到远程调试端中3》双开IDA工具,一个是用来打开so文件,进行文件分析,比如简单分析arm指令代码,知道大体逻辑,还有就是找到具体函数的相对位置等信息,还有一个IDA是用来调试so文件的,我们在Debugger选项中设置Debugger Option,然后附加需要调试的进程4》进入调试页面之后,通过Ctrl+S和G快捷键,定位到需要调试的关键函数,进行下断点5》点击运行或者快捷键F9,触发程序的关键函数,然后进入断点,使用F8单步调试,F7单步跳入调试,在调试的过程中主要观察BL,BLX指令,以及CMP和CBZ等比较指令,然后在查看具体的寄存器的值。2、IDA调试有反调试的so代码步骤:1》查看apk是否为可调式状态,可以使用aapt命令查看他的AndroidManifest.xml文件中的android:debuggeable属性是否为true,如果不是debug状态,那么就需要手动的添加这个属性,然后回编译,在签名打包从新安装2》使用adb shell am start -D -n com.yaotong.crackme/.MainActivity 命令启动程序,出于wait Debug状态3》打开IDA,进行进程附加,进入到调试页面4》使用jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700 命令attach之前的debug状态,让程序正常运行5》设置Debug Option选项,设置Suspend on library start/exit/Suspend on library load/unload/Suspend on process entry point选项6》点击运行按钮或者F9键,程序运行停止在linker模块中,这时候表示so文件加载进来了,我们通过Ctrl+S和G键跳转到JNI_OnLoad函数出,进行下断点7》然后继续运行,进入JNI_OnLoad断点处,使用F8进行单步调试,F7进行单步跳入调试,找到反调试代码处8》然后使用二进制软件修改反调试代码为nop指令,即00值9》修改之后,在替换原来的so文件,进行回编译,从新签名打包安装即可10》按照上面的无反调试的so代码步骤即可第四、学习了如何做到反调试检测现在很多应用防止别的进程调试或者注入,通常会用自我检测装置,原理就是循环检测/proc/[mypid]/status文件,查看他的TracerPid字段是否为0,如果不为0,表示被其他进程trace了,那么这时候就直接退出程序。因为现在的IDA调试时需要进程的注入,进程注入现在都是使用Linux中的ptrace机制,那么这里的TracePid就可以记录trace的pid,我们可以发现我们的程序被那个进程注入了,或者是被他在调试。进而采取一些措施。第五、IDA调试的整体原理我们知道了上面的IDA调试步骤,其实我们可以仔细想一想,他的调试原理大致是这样的:首先他得在被调试端安放一个程序,用于IDA端和调试设备通信,这个程序就是android_server,因为要附加进程,所以这个程序必须要用root身份运行,这个程序起来之后,就会开启一个端口23946,我们在使用adb forward进行端口转发到远程调试端,这时候IDA就可以和调试端的android_server进行通信了。后面获取设备的进程列表,附加进程,传递调试信息,都可以使用这个通信机制完成即可。IDA可以获取被调试的进程的内存数据,一般是在 /proc/[pid]maps 文件中,所以我们在使用Ctrl+S可以查看所有的so文件的基地址,可以遍历maps文件即可做到。破解法则:时刻需要注意关键的BL/BLX等跳转指令,在他们执行完之后,肯定会有一些CMP/CBZ等比较指令,这时候就可以查看重要的寄存器内容来获取重要信息。七、总结总算是说完了IDA调试so了这个知识点,我们也知道了一种全新的方式去破解native层的代码,现在有些程序依然把关键代码放在了Java层,那么这里我们可以使用Eclipse调试samli即可破解,如果程序为了安全,可能还会把关键代码放到native层,那么这时候,我们可以使用IDA来调试so代码来破解,当然破解和加密总是相生相克的,现在程序为了安全做了加固策略,那么这也是我们下一篇文章需要介绍的,如何去破解那些加固的apk。更多内容:PS: 关注公众号,最新Android技术实时推送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

我要回帖

更多关于 现在食用的结球白菜 的文章

 

随机推荐