文档章节

【腾讯Bugly干货分享】iOS黑客技术大揭秘

腾讯Bugly
 腾讯Bugly
发布于 2016/07/28 19:56
字数 5772
阅读 104
收藏 2
点赞 0
评论 0

本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5791da152168f2690e72daa4

“8小时内拼工作,8小时外拼成长”这是大家共同的理想。除了每天忙于工作外,我们都希望能更多地区吸收领域内的新知识与新技能,从而走向人生巅峰。

Dev Club 是一个交流移动开发技术,结交朋友,扩展人脉的社群,成员都是经过审核的移动开发工程师。每周都会举行嘉宾分享,话题讨论等活动。

上一期我们邀请了腾讯 WXG iOS 开发工程师“姚海波”分享了**《微信读书 iOS性能优化》**。

本期,我们邀请了腾讯 CDG iOS 开发工程师“何兆林”为大家分享**《iOS黑客技术大揭秘》**。

如何加入 Dev Club?

移动端开发经验 >= 2 年,微信扫描下方群管理微信二维码,备注姓名-公司(或产品) 申请加入。

外部群二维码


分享内容简介:

在黑客的世界里,没有坚不可破的防护系统,也没有无往不胜、所向披靡的入侵利器,有时候看似简单的问题,破解起来也许花上好几天、好几个月,有时候看似很 low 的工具往往能解决大问题;我们以实现微信自动抢红包为引子,逐步展开 iOS 黑客入侵常用的几种武器,并简单的讲解一些常用的反入侵策略,以及如何破解反入侵策略,虽然抢红包的破解代码网上有很多,但是我们要讲的是这些代码是用什么工具分析出的,为什么要这样写?

内容大体框架:

  1. 让目标程序破茧而出 -- dumpdecrypted
  2. 运行时分析 -- cycript
  3. 追踪神器 -- logify
  4. 反汇编工具 -- hopper
  5. 断点调试工具 -- lldb+debugserver
  6. 注入工具 -- insert_dylib + install_name_tool

分享人介绍: 何兆林 通讯充值与彩票业务部 iOS开发工程师。

负责过的产品:QQ彩票、QQ电影票 iOS客户端,目前主要负责 QQ彩票 iOS客户端的开发。


下面是本期分享内容整理


大家晚上好,我是来自 CDG的 jolinhe,目前在做qq彩票项目,负责 iOS侧的插件化和整体架构。

越狱和入侵是我的业余爱好,正好08和09年的时候,在网龙积累了一些越狱开发经验,所以今天跟大家分享一下 iOS入侵方面的工具和手段。

为了避免纸上谈兵:

  • 第一部分我们就拿微信来开刀,讲解一下如何运用这些工具来找到和实现自动抢红包功能的;
  • 第二部分我们再总结一下常用的入侵原理和反入侵方法。

开始之前,我们需要把环境搞起,硬件方面,需要:

  1. 一台越狱手机
  2. 一台装了开发环境的 Mac电脑

软件方面内容提纲已经列出来了,需要注意的是它们有一些是手机端的,一些是 PC端的,用到的时候我会细讲。

群里不乏老司机,这里我假设大家对于 ssh、theos、class_dump、hook这些工具和技术都已经有所涉猎了,如果有不清楚的,欢迎私下交流。

一、微信实现自动抢红包功能

言归正传,要实现自动化抢红包,首先我们需要理清思路:

  • 第一步:需要拦截微信的消息流,在哪里拦截?
  • 第二步:在这些信息流中分辨出哪些消息是红包?
  • 第三步:在合适的地方插入自己的“抢”红包代码。

1、让目标程序破茧而出——dumpdecrypted

因为直接从 AppStore下载下来的二进制文件都是加了壳的,所以为了让它的内核破茧而出,我们需要砸壳操作。

所以第一个工具就是 dumpdecrypted,这个工具是手机端的,可以通过 cydia安装,安装后文件路径是:

/usr/lib/dumpdecrypted.dylib

在实际使用时,可以通过 pp助手把这个文件 copy到目标程序的 documents目录,然后ssh进手机终端,cd到 documents目录,执行:

DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib WeChatPath

执行完后会再 documents目录生成一个砸完壳后的二进制文件

2、运行时分析——cycript

砸完壳之后,我们再 dump出头文件,但是微信的类太多了,头文件有几百个,如此多的头文件,让人眼花缭乱,所以要找到突破口,我们得缩小范围,我喜欢用的思路是从 ui入手,先找到微信对话界面的 controller,然后再追踪 controller中对应的消息处理函数。

这样第二个工具 cycript 隆重出场了,它也是个手机端的工具,用于查看 app运行时数据,大伙儿可以通过 cydia安装,安装完之后,ssh到越狱手机的终端。

先找到微信的进程id:ps aux | grep WeChat
再执行:cycript -p 微信的pid

完成了注入,进入到 cycript提供的终端。

这时候进入在手机上进入微信的聊天窗口,例如:

然后在 cycript的终端输入:

UIApp.keyWindow.recursiveDescription().toString()

结果如下:

打印的是当前的ui树,随便找一个节点(树的中间,为什么要在中间,大家可以思考下),copy它的内存地址,例如 0x14da3f000

执行:[#0x14da3f000 nextResponder]

会输出当前节点的下一级事件响应链,然后对输出节点再次调用 nextResponder,直到找到它的视图控制器 xxxcontroller

看到了吧,微信的聊天页对应的类名是 BaseMsgContentViewController

3、追踪神器 -- logify

目前为止我们已经锁定了大致的突破口,下面还需继续追踪,找到这个类里面的消息处理函数,这里的思路就是通过向群里发送一个消息,然后观察 controller中哪些方法被调用了。

第三个工具 Logify就是干这个事情的,它是 theos的一个组件,和 theos一起安装在 pc端的,在 pc的终端输入:

logify.pl /path/to/BaseMsgContentViewController.h > /out/path/to/Tweak.xm

打开生成的 tweak.xm文件,可以看到它其实就是 hook了这个类所有的方法,在方法中注入了 nslog,打印方法的入参和返回值,最后把这个文件用 theos打包并安装到手机中,再次向群里发消息,手机连上 xcode观察手机控制台输出。

输出内容很多,需要仔细过滤一下,例如我们发的消息是一个文本“test”,在控制台搜索它,你会在它附近找到下面这个函数调用:

addMessageNode:layout:addMoreMsg

从函数名字来看,这个应该就是用来处理消息数据的,从表面来看我们已经找到消息的拦截点了,但是大家想一下,如果我们hook这个方法,在里面自动抢红包,会有什么致命的缺陷?

老司机们已经看出来了吧,这个方法是 BaseMsgContentViewController类里面的,而这个类进入聊天页面才会被创建。

hook这里会有两个缺陷:

  • 第一,必须进特定的群的聊天页面才能生效;
  • 第二,两个群同时有红包来,没法并发的抢。

为了追求更加上流的功能,我们需要再向上追溯消息的源头,最好 hook那种微信启动后就存在的对象,怎么追溯呢?

我的思路是通过在这个方法中设置断点,通过调用栈,来找到上层的调用者。

4、反汇编工具——hopper & 断点调试工具——lldb + debugserver

第五个工具 lldb + debugserver顾名思义,debugserver是手机端的(只要你的手机有连过 xcode进行 debug,这个玩意就自动有了),用于监听 pc端 lldb的连接,来实现远程调试。

这个工具要和**第四个 hooper(反汇编工具)**结合起来用。

首先 ssh进手机的终端,输入:

debugserver *:19999 -a WeChat

监听 lldb的连接

然后打开pc的终端,启动 lldb并连接:

lldb
process connect connect://deviceIP:19999

如果连接成功,我们就正式进入 debug状态了。

那么问题来了,要精确的设置断点,必须知道这个函数的内存地址,这个内存地址怎么搞出来呢?

有个公式:

内存地址=进程内存基地址+函数在二进制中的偏移量

上面我们已经连上了 lldb调试环境,获取基地址在 lldb中输入下面的命令:

image list -o -f

这时会输出很多行数据,找到文件名为 WeChat的模块地址,这里第一行就是了:

偏移量需要借助 hooper,pc端的反汇编利器,用 hooper打开微信的二进制文件,等几分钟,反汇编完成后,在搜索框输入刚找到的函数名: addMessageNode,定位到相应的汇编代码,第一列就是偏移量了:

两个参数都找到后,在lldb中输入:

br s -a ‘基地址+偏移量’

然后用 “br l” 确认一下断点是否设置成功

进入聊天界面,再次向群发送一个消息,会发现 ui卡住了,观察 lldb控制台,会提示进程被断住了,在 lldb中继续输入 bt指令,重点观察模块名是 WeChat的栈,但是由于没有符号表,我们只能看到栈的内存地址:

想要把内存地址还原成函数名,需要两步:

  • 第一要把内存地址转换成二进制文件偏移量
  • 第二步再使用 hooper根据偏移量找到函数名

也就是上面公式的逆向过程:

函数在二进制中的偏移量=内存地址 - 进程内存基地址

这里我们栈地址是0x0000000101ad02f4,基地址是0x00000000000e8000,做下减法,得到结果0x1019E82F4,然后在 hooper中搜索这个地址就能得到方法名:

以此类推,最后得到栈顶的调用是这个:

[CMessageMgr MainThreadNotifyToExt:]

CMessageMgr这个类,从名字来看,就是消息管理器,而且是单例的,我们终于找到了真正需要 hook的类,但是这个方法是用来异步发送通知的,不像是消息的源头,所以我们用上面说的 logify组件继续追踪一下这个类

过程不再重复讲,最后的目标终于浮出水面:

(void)AsyncOnAddMsg:(id)message MsgWrap:(CMessageWrap* )msgWrap

第一步消息的拦截点终于找到了,接下来是第二步:

**第二步:**我们需要知道哪些消息是红包,这个就比较简单,向群里发一个普通消息和红包消息,通过 logify组件观察 message参数的内容,发现它里面有一个 type字段,如果是红包,值是49,其他语音和文本各不相同,所以,这里轻松搞定。

第三步:需要实现抢红包代码,这一步稍微复杂一点,先讲一下思路,首先进入微信开红包的界面:

根上面讲过的一样,通过 cycript+logify我们可以轻松拿到开红包的入口函数,下一步,我们需要自己从 AsyncOnAddMsg的参数中构造抢红包函数的入参。

找注入点我就不再重复讲,直接上结果:

[WCRedEnvelopesReceiveHomeView OnOpenRedEnvelopes]

这显然是一个事件处理函数,它里面肯定会调用真正的拆红包逻辑

所以我们打开 hooper,找到这个方法然后观察方法体,发现它在最后调用了一个 selector:

WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes

这应该是真正的拆红包逻辑,但是这个 selector没有参数,所以我猜想这个方法的作用应该是自己封装拆红包所需的数据,并调用底层服务来拆红包。

在hooper中搜索这个方法,观察一下,果然是这样的:

函数开始部分的汇编代码都是在构造dictionary,只有在最后调用了一个可以函数:

这里说明一下,由于微信这一块的代码全都是 oc的,而 hooper可以直接将 oc反汇编到接近源码的水平,所以,还原过程基本不需要掌握多少汇编知识,具体的还原过程可以看下我之前发的文章:http://blog.csdn.net/heiby/article/details/51792151

最后一步,编写 tweak,替换 AsyncOnAddMsg函数并把自己的成果注入进去就 ok了。

6、注入工具——insert_dylib + install_name_tool

对于越狱机器来说,到这里已经大功告成了,但是想要在非越狱机器上跑,还需要几个步骤:

在非越狱机上面,一切都要靠自己,首先手动把你的库注入到目标二进制中,这一步使用 insert_dylib就可以了,它运行在 pc端,在命令行 cd到微信的二进制目录,执行命令:

insert_dylib @executable_path/xxx.dylib WeChat

因为我们的 hook代码是基于 cydiaSubstrate的,用l -L xxx.dylib来检查一下你的 tweak,这个依赖库在正版机上是没有的,我们需要把它从越狱机充 cp出来和你的 tweak一起拖进目标 app目录,并通过install_name_tool命令修改你的 tweak中对他的引用路径。

最后,用 codesign命令对微信 bundle里面所有的 dylib进行签名:

codesign -f -s "iPhone Developer:xxx" xxx.dylib

打包成ipa:

xcrun -sdk iphoneos PackageApplication -v WeChat.app -o ~/WeChat.ipa

再使用 iResign对 ipa进行签名,就可以安装到非越狱的机器上了。

注意一下,如果你不想使用 iResign,在执行 xcrun之前,还需要对微信的二进制文件进行签名:

codesign -f -s "iPhone Developer:xxx” —entitlements Entitlements.plist WeChat.app

经常有人问 Entitlements.plist文件怎么写?照着这个来就行了,把 teamed和 bundle id改成你自己的:

签名完成后可以通过ldid命令查看签入的内容:

ldid -e /path/to/WeChat

到这里入侵圆满结束!

二、常用入侵原理和反入侵方法总结

下面我们总结一下用到的几个工具:

  • dumpdecrypted
  • insert_dylib
  • cycript

第一个工具是砸壳用的,代码是开源的,而且相当简单,它并没有破解 appstore的加密算法,而是把自己注入到已经通过系统加载器解密的 mach-o文件,再把解密后的内存数据 dump出来,详细的原理这篇文章写的很清楚:http://bbs.iosre.com/t/dumpdecrypted/465

那他是怎么注入的呢?就是利用了 iOS系统中 DYLD_INSERT_LIBRARIES这个环境变量,如果设置了 DYLD_INSERT_LIBRARIES 环境变量,那么在程序运行时,动态链接器会先加载该环境变量所指定的动态库;也就是说,这个动态库的加载优先于任何其它的库,包括 libc。

由于这个环境变量指定的动态库加载的时机实在是太早了,所以对于 app来说,除了代码混淆外,无良策;

但是我们可以在代码中通过判断环境变量来检测是不是被注入:

charchar *env = getenv("DYLD_INSERT_LIBRARIES");

如果方法返回非空,我们可以做一些上报之类的。

后面两个工具都是用来注入的

insert_dylib通过向 mach-o文件的 loadcommand段插入 LC_LOAD_DYLIB数据来加载第三方库。

对于 insert_dylib,我们可以通过在 Xcode的Build Settings中找到“Other Linker Flags”在其中加上-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null指令来绕过 dylib加载额外的第三方库,具体的原理可参考 http://bbs.iosre.com/t/tweak-app-app-tweak/438

但是破解这一招也非常简单,上面的链接也说了,用 0xED打开二进制文件,把__RESTRICT全局替换成其它名字即可。

cycript个人感觉是比较神奇的,它在进程运行时动态注入。

没有细看它的源码,网上资料称,它通过 taskfor_pid函数获取目标进程句柄,然后通过在进程内创建新线程并执行自己的代码。

对于 cycript这种 bt的行为,利用系统的 root权限在进程中创建线程并执行自己的代码,目前还没想到好的对策,如果有老司机有方法,希望能指导一下~

最后再说说 lldb反调试,网上大多都提到 ptrace系列函数,原理我就不多说,这里主要讲如何绕过它,有两种方法,先说第一种,直接通过汇编代码修改 ptrace的第一个参数,这样我们需要先知道在哪里调用了 ptrace。

用backboard服务启动启动目标程序:

debugserver -x backboard *:19999 /path/to/binary 

在pc端用lldb连接:

process connect connect://deviceIP:19999

然后在lldb中下符号断点

b ptrace,

在lldb中输入c命令之后看ptrace第一行代码的位置,继续输入命令:

p/x $lr 

找到函数返回地址,然后用:

image list -o -f

找到目标程序的基地址,这样就能用上面说的公式计算出偏移量,最后在 hooper中找到调用 ptrace的汇编代码

找到汇编代码的位置后,把 ptrace的第一个参数 1F,替换成 0A即可,下面是我的调试过程:

手机端:

pc端:

第二种简单又暴力,注入tweak,让 ptrace直接返回0即可,具体的代码非常简单,直接发出来:

//Tweak.xm
#import <substrate.h>
#import <mach-o/dyld.h>
#import <dlfcn.h>

static int (*oldptrace)(int request, pid_t pid, caddr_t addr, int data);
static int newptrace(int request, pid_t pid, caddr_t addr, int data){
	printf("newptrace:%d\n\n",request);
	return 0;
}
%ctor {
	printf("Tweak for SkipPtrace  Start!\n\n");
	MSHookFunction((void *)MSFindSymbol(NULL,"_ptrace"), (void *)newptrace, (void **)&oldptrace);
}

总结

入侵的路有很多条,关键是要在开始阶段定好目标,并理清思路,不然很容易走进各种死胡同,还要学会面对失败,不要一条路走不通就放弃,最后呢,我们要善于借助各种工具,能用工具,干嘛还要去费力气。

今天分享就到这里,下面大家有问题可以提问哦!

问答环节

Q1:其实我挺好奇,这个能被破解,应该也会有被封堵的问题吧?

我们这里只是伪造了自己的参数,并调用微信原有的逻辑自动拆红包,所以技术上出了微信更新版本,是封不了的,但是如果你抢的太暴力,账号有可能被封,这里我们可以通过随机的延迟等操作来避免

Q2:我在分析 UI时候多用了一个 reveal的工具。

reveal的可视化做的比较强大,用来分析 ui很不错,有需要可以用

Q3:想问问那些安全类软件是如何防止 tweak,对微信支付宝的进程保护?

防止tweak上面我也讲到一些,不过都是从目标 app的代码层级来讲的,例如反 gdb和反注入,对于安全类软件来说,在非越狱的系统上,基本起不了作用,在越狱机上面,由于有 root权限,这时就能做很多事情了,例如检查 mach-o文件的 loadcommand、检查 DYLD_INSERT_LIBRARIES这种环境变量等

Q4:各种微信分身版能被微信后台准确的识别出来吗?如果可以识别,有哪些方方法可以去识别?

您指的是一机多装吧,ios系统通过 app的 bundleid来唯一识别一个 app,分身版大多是通过改 bundleid并重新签名和发布,在代码中可以通过监控自己 info.plist里面的 bundle id来识别是否被篡改,但是这也是不可靠的,因为黑客们还是可以通过 hook你的监控函数来绕开

Q5:看到你不少是根据方法名字面上来猜想它的意思,要是有的 app代码写的烂,我们反而不好弄了吧?还有如果红包的核心代码是用 C/C++的代码,这是不是就不能这样反汇编了?

确实会这样,代码写得烂,有点类似于“代码混淆”,会增加入侵的难度,如果核心代码是 c/c++,在汇编层面会增加阅读难度,但是只是难度增加了而已

Q6:对于哪些包括 watch和 extension的 App,在重签名时有哪些需要注意的呢? 重签名安装成功但启动就闪退可能是什么原因?

有 extension的app,在重签名时,需要记住每个 extension都需要用同样的证书单独签名,然后再对外层的 ipa进行签名,重签名后启动闪退,可以通过 xcode连接设备,点击 window->devices查看设备控制台,在控制台,会输出你那一个 dylib校验失败,还有失败的原因

Q7:听你分析逆向这么容易,那 ios防反编译有哪些方案?

ios防止反编译主要还是代码混淆,但是混淆的代价大家是知道的,而且混淆也不能完全阻止入侵,所以会得不偿失,因为这样,现在 ios开发很少用;还有一个方案就是反注入,上面讲过的,但是很容易被绕过

Q8:Android的一个安全加固保护是通过设置 PTRACEME来防止外部程序来 ptrace自己,如果 iOS APP也这样设置了,会不会导致其中一些逆向机制失效呢?

ptrace只是反调试的,不会影响逆向过程

更多精彩内容欢迎关注bugly的微信公众账号:

腾讯 Bugly是一款专为移动开发者打造的质量监控工具,帮助开发者快速,便捷的定位线上应用崩溃的情况以及解决方案。智能合并功能帮助开发同学把每天上报的数千条 Crash 根据根因合并分类,每日日报会列出影响用户数最多的崩溃,精准定位功能帮助开发同学定位到出问题的代码行,实时上报可以在发布后快速的了解应用的质量情况,适配最新的 iOS, Android 官方操作系统,鹅厂的工程师都在使用,快来加入我们吧!

© 著作权归作者所有

共有 人打赏支持
腾讯Bugly
粉丝 276
博文 134
码字总数 568948
作品 0
深圳
BUF 早餐铺 苹果iPhone X iOS 11.3.1被腾讯Keenlab团队成功越狱;WhatsApp联合创始人Jan Koum因隐私问题离开Fa...

  各位 Buffer 早上好,今天是 2018 年 5 月 3 日星期六,农历三月十八。今天的 BUF 早餐铺内容主要有:苹果iPhone X iOS 11.3.1被腾讯Keenlab团队成功越狱;WhatsApp联合创始人Jan Koum因...

FreeBuf ⋅ 05/03 ⋅ 0

iOS12 beta 1系统被攻破,越狱视频被分享

半个月前,iOS 12 在 WWDC 2018 苹果全球开发者大会上正式亮相,开发者用户开始下载iOS 12 开发者预览版 Beta1 固件进行升级体验。 十几天后,6月17日凌晨2点,腾讯科恩团队在推特分享了iOS...

又田 ⋅ 今天 ⋅ 0

iOS最火那年转型管理,他收获了什么?

过去一年,移动端开发者就业环境爆冷。一些迷茫的程序员,通过转岗甚至转行的方式,暂时告别自己的移动开发路。 提到转型,作为国内最早的一批 iOS 开发者,唐巧相当有发言权。工作八年,他恰...

100offer ⋅ 04/13 ⋅ 0

瞬间被打脸:苹果的iOS 12 USB 封锁模式还未发布就已沦陷

        前言   6月5日,苹果宣布他们在iOS 12系统中加了新的安防取证措施,以防止像Grayshift这样的取证服务商任意读取数据。不过6月15日,根据Vice的一份最新报告显示,Grayshift...

嘶吼RoarTalk ⋅ 昨天 ⋅ 0

阿里腾讯百度头条美团iOS面试总结

阿里腾讯百度头条美团iOS面试总结 2018-05-30 15:24编辑: garace分类:程序人生来源:代码湾 互联网面试iOS 招聘信息: C++工程师 Cocos2d-x游戏客户端开发 iOS开发工程师 京东招聘iOS开发工...

garace ⋅ 05/30 ⋅ 0

【阿里聚安全·安全周刊】Google“手枪”替换 | 伊朗中央银行禁止加密货币

本周七个关键词:Google“手枪”替换丨IOS 漏洞影响工业交换机丨伊朗中央银行禁止加密货币丨黑客针对医疗保健丨付费DDoS攻击丨数据获利的8种方式丨MySQL 8.0 正式版 8.0.11 发布 -1- 【互联网...

聚安全平台 ⋅ 04/27 ⋅ 0

2018 一份"有点难"的iOS面试题(5年iOS开发)

序言: 之前一时兴致在本站上出过一份iOS的中级面试题,引起一些关注,不少同学表示对”隐藏关卡“感兴趣。升级版iOS面试题来了,目测难倒90%iOS程序员,目测一大波程序员撸着袖子在靠近。 ...

原来是泽镜啊 ⋅ 05/26 ⋅ 0

BUF早餐铺 任天堂Switch破解漏洞已公开,可加载Linux玩模拟器;黑客劫持MyEtherWallet的DNS服务器窃取超130,00美元;非法获...

  各位 Buffer 早上好,今天是 2018 年 4 月 26 日星期四,农历三月十一。今天的 BUF 早餐铺内容主要有:任天堂switch破解漏洞已公开,可加载Linux玩模拟器;SMT项目现安全漏洞,火币Pro暂...

FreeBuf ⋅ 04/26 ⋅ 0

聚焦技术实战!MDCC 2016 移动开发者大会盛大开幕

9月23日-24日,“MDCC2016移动开发者大会●中国”(MobileDeveloperConferenceChina2016,简称MDCC2016)在北京●国家会议中心隆重召开。本次大会由全球最大中文IT社区CSDN和中国最具关注度的...

玄学酱 ⋅ 05/15 ⋅ 0

一样的iOS开发程序员为什么有人4k有人40k?

前言 移动开发真正火起来其实就是最近这几年,iOS 开发技术因为发展也就才这么几年,所以值得做的事情还有很多,这就造成了每年苹果的 WWDC 都会推出一堆新的特性和 API。整体上来说,这对业...

原来是泽镜啊 ⋅ 05/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

vim介绍、vim颜色显示和移动光标、vim一般模式下移动光标、一般模式下复制粘贴剪切

VIM Vim 是 UNIX 文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff),语法高亮,全面的帮助系统,本地脚本(Vimscript),和便于选择的...

蛋黄Yolks ⋅ 15分钟前 ⋅ 0

springboot+mockito测试controller层遇到的问题

使用MockitoJUnitRunner测试的一个例子,原来报错无法找到bean, 类似的异常如下:createBeanError..... 原因:是因为@Runwith使用了SpringRunner,应该修改为MockitoJUnitRunner 代码如下: ...

writeademo ⋅ 27分钟前 ⋅ 0

关于“幂等”操作

一个幂等(idempotent)操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同. 开发中, 我们经常考虑幂等操作的场景有“接口调用”、“MQ消费”、“自动任务”等 接口调用, 可能出现...

零二一七 ⋅ 35分钟前 ⋅ 0

Dubbo服务服务暴露之ProxyFactory Invoker

Dubbo服务暴露过程中有涉及到调用ProxyFactory 中方法获取Invoker对象的过程,现在我们来深究下源码,来看下这个过程是在做些什么,返回的Invoker 对象是什么,我们来看一下代码的切入点: ...

哲别0 ⋅ 49分钟前 ⋅ 0

GP两种连接方式性能测试

GP两种连接方式性能测试 Pivotal import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; public class GPQueryStrin......

仔仔1993 ⋅ 54分钟前 ⋅ 0

jsonrpc-4j代码解析

解析文件 AutoJsonRpcServiceImplExporter JsonServiceExporter AutoJsonRpcServiceImplExporter 路径:com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter AutoJsonRpcServi......

郭恩洲_OSC博客 ⋅ 今天 ⋅ 0

百度搜索

from selenium import webdriver import time brower=webdriver.Firefox() brower.get('http://www.baidu.com') input=brower.find_element_by_id('kw') input.send_keys('中南大学') time.s......

南桥北木 ⋅ 今天 ⋅ 0

tomcat 日志记录器

1、日志记录器是记录消息的组件 日志记录器需要与某个servlet 容器相关联 2、Logger 接口 共定义了5种日志级别:FATAL、ERROR、WARNING、INFORMATION、DEBUGGER setVerbosity 设置级别 setC...

职业搬砖20年 ⋅ 今天 ⋅ 0

Thrift RPC实战(三) Thrift序列化机制

1.Thrift基础架构 Thrift是一个客户端和服务端的架构体系,数据通过socket传输; 具有自己内部定义的传输协议规范(TProtocol)和传输数据标准(TTransports); 通过IDL脚本对传输数据的数据结构...

lemonLove ⋅ 今天 ⋅ 0

网站建设就要像2018世界杯的俄罗斯队大杀四方[图]

今天心情不错,因为昨天晚上观看了世界杯比赛,尤其是对俄罗斯队的大杀四方感到十分霸气侧漏啊,因此我联想到了自己的博客网站,我的博客是去年年底上线的,一直想建设一个关于读书和读后感作...

原创小博客 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部