许久没有更新过blog,看了下前一次发的东西还是8年前。这段时间终于有闲心和时间写写文章,准备重新捡起来写写想说的话,不限于技术了。
HideKd v0.3
收到个Blog留言找这个东西的。没想到这么多年前的东西还有朋友需要。这里放一份上来吧,因为DbgTech网站的论坛被我撤掉了,老的已经比较难找。当年做安全的时候做的玩具,权当娱乐大众。
HideKd v0.3
Hide WinDbg、KD from detected.
Load
1、Run HideKd.exe to load HideKd.sys.
2、Enjoy yourself
History
v0.3
Fix some bug.
v0.2
Add driver loader HideKd.exe.
v0.1
Skip KdDebuggerEnabled,KdEnteredDebugger detect.
Skip SharedUserData->KdDebuggerEnabled detect.
Skip NtQuerySystemInformation detect.
点击下载:HideKd
VMWare 11.0 装MacOS补丁
修改了个Command Bar v3.20.110 用来支持 Ollydbg 2.01 final
September 27, 2013 – version 2.01的Olly dbg 2.01中使用Command Bar v3.20.110会在启动后崩溃。原因是OD加载插件后对比返回的版本,发现插件支持的版本小于当前版本号会FreeLibrary。Command Bar在前面的初始化中做了SubClass,但是在DLL DETACH中没有正确反初始化,造成call WndProc的时候崩溃。修改返回的2010000版本号为2010001解决。
点击下载:CmdBar
另外,也可以直接修改OD2下面位置的代码解决:
004D878E |. 81FF 01000102 |cmp edi, 2010001
这里放一个跳过了插件版本判断的ollydbg.exe
点击下载:ollydbg
针对GFW不定期封杀VPN的对策
从去年开始就发现VPN不定期的出现异常。断断续续忍受着用了将近1年,还是找了个办法搞定。记录一下方便后来者。
我之前的VPN是搭建在自己Linux VPS上的pptpd服务器。某次GFW升级后常常出现连接超时或者在帐号认证的步骤超时,错误码常常为800或者7xx。因为目前GFW针对VPN标准协议处理得比较完善,所以改用SSH隧道+Sock5代理的形式。Sock5代理可以用putty的SSH隧道功能方便的开启一个本机代理端口,然后采用Proxifier作为客户端连接到本地的SSH代理端口上。SSH因为有安全连接层,而且正常的业务访问使用得很多,GFW在封杀上会相对比较保守,应该能够顶上不少时间。
ATF格式图片批量转换工具
Thanks Andreas L?w for his great work on TexturePacker
Android inline hook手记
NetRoc
许久没搞安全方面的东西了。最近有些时间看了看android下面的开发,看去看来总是想往内深入,结果又往Native和内核挖过去了……
研究了一下ARM架构下面的inline实现,网上搜了搜似乎没有找到多少资料。想了想还是写出来吧,当作笔记。由于时间不多,也不是为工作而看,仅仅是做了粗略的实现和研究,并没有深入下去。这篇手记的目的不在于详细描述整个HOOK实现的过程,而仅仅对一些关键点作一些描述。
说到Inline hook,了解这个词的同志们都应该知道,无非是修改目标函数处的指令,跳转到自己的函数,并且提供调用原函数的stub,即可完成整个流程。但是在ARM下面情况和我们熟悉的x86有所不同。ARM芯片的运行状态分为arm和thumb两种模式,分别有不同的指令集,arm指令为定长32位,thumb指令为定长16位(thumb-2中进行了扩展,可以使用32位thumb指令)。同一段代码中可以混用两套指令集,通过一些带有interworking功能的跳转或者load指令可以在两种模式间切换。做ARM下的inline,首先遇到的就是指令模式的问题。另外,ARM架构下,CPU也具有分开的指令缓存和数据缓存,类似x86下的DTLB和ITLB。但是在实现过程中发现,arm的缓存作用非常明显,而且刷新机制不太确定,因此自修改代码需要经常主动控制缓存的刷新。这一点,可以通过NDK的API cacheflush实现。
下面简单说说一些主要问题:
-
关于页保护
这一点对于熟悉Linux编程的同志们应该不是问题,mprotect修改为PROT_READ | PROT_WRITE | PROT_EXEC即可。页面大小可以通过包含ndk下面<asm/page.h>文件,里面定义的一系列宏用于获得页面大小和进行对齐运算。
-
关于模式转换和跳转
Arm下主要的分支指令如BX,BLX等,都可以切换指令模式。详见arm的用户手册。这里主要讨论模式的选择和切换时机。只有一个问题需要注意,arm处理器执行时,由于流水线的关系,会预取两条指令,因此当前指令取到的pc值,始终是之后第三条指令的地址。比如当前指令地址是0x8000,那么当前pc的值,在thumb下面是0x8000 + 2 * 2, 在arm下面是0x8000 + 4 * 2。
由于运行时我没有找到简便的办法能够确切知道被hook的目标函数指令集,所以这个问题留给了hook的使用者来决定。Hook之前应通过逆向工具获知所有目标函数是arm还是thumb指令。
如果要根据目标函数指令集的不同而对hook函数采用不同的 编译选项,显然是一件麻烦的事情。而arm模式的指令由于单条指令包含的语义更多,是我们的首选。因此可以考虑主仅使用arm指令编译hook函数,而在跳转的同时切换到arm模式。
关于跳转插入的指令方面,由于arm指令带立即数的跳转范围只有4M,thumb的跳转范围只有256字节。所以首选ldr pc,xxxx指令来实现。对于arm指令的目标,这个指令很容易选择。如下:
ldr pc, [pc,#-4]
32位跳转绝对地址
指令为单个32位数字:0xE51FF004。
但是thumb模式下的16位ldr指令没有办法向pc中load,选择就很成问题。如果单纯使用16位thumb指令的话,跳转部分需要占用大量字节数,而因为arm下面编译器常常使用pc的值作为基址来计算地址,被搬动过的指令中就极有可能存在这种指令。搬动过后的代码中就必须对这部分指令进行修正,而又由于thumb所能够支持的立即数很小,跳转范围也很小,这种修正往往非常麻烦,需要用几条同等指令来替换一条指令。经过考虑,还是决定放弃对ARMv5的支持,直接使用ARMv6T2之后支持的thumb-2指令集。thumb-2支持32位thumb指令,也支持ldr以pc为目标寄存器:
ldr.w pc,[pc,#0]
32位跳转绝对地址
指令为单个32位数字:0x00F0DFF8
所有需要跳转的地址,需要注意的是bit0的处理。如果bit0为1,跳转后会切换到thumb指令模式,如果bit0为0,会切换至arm模式。当目标为arm的时候,我们不需要特殊处理,编译器会处理地址的计算。但是当目标为thumb的时候,从hook指令跳转到hook函数,以及调用原始函数的时候,都需要注意地址bit0的处理。
-
关于搬出来的原始指令
按照win32下Detours库的实现方式,被HOOK函数的前面几条指令,会搬到一个trampoline中,并在这些指令后添加跳转至原代码后续部分的指令。在搬动过程中,需要对被移动的指令进行地址修正。在处理ARM平台inline的过程中也需要作这样的工作。但是实际上在处理的时候会发现,要做到这一点是非常困难的。ARM下常常会生成下面这种将pc作为地址参照的指令块
而由于arm平台寻址范围较小,编译器通常选择将数据和指令在内存中的存放混杂在一起。thumb模式下,由于指令中能包含的立即数非常小,这种问题会表现得异常突出,修正的时候也常常一条指令被拉长为数条。因此代码修正会有非常大的工作量。这部分问题由于太消耗时间,我也仅仅是对arm下的inline进行研究性实现,也就没有管这个问题了。实际项目如果要用到hook,这个部分花费的时间应该比单纯hook跳转的实现要大得多。在不考虑并发和效率的情况下,当hook函数中要调用原函数时,可以考虑临时恢复hook,并在调用完成后再次hook来解决。但是始终是相当不优雅的实现。
-
关于线程处理
修改hook目标的指令时,和x86平台下一样,也需要注意有可能某些线程刚好执行到被修改的指令中的问题。Win32下可以枚举线程并修改context到被搬迁的指令中去。但是Linux内核系统下很难进行线程的控制。估计可以采用接管信号处理,并向进程内所有线程调用pthread_kill来实现。
Starling bitmap font viewer
Features:
- Support for startling bitmap font format view.
- Support png,jpg,gif,bmp texture format
- Support xml .fnt file format.
功能:
本软件用于查看Starling兼容格式的位图字体。支持png,jpg,gif,bmp格式的材质文件,以及XML格式的字体描述文件。
修正了上一个版本显示字体颜色全部为黑色的问题。现在能显示材质中真实颜色了。
Download:
AS3 TGA Codec
这段时间研究了一下AS下面的图像格式。测试了一下,TGA格式图片经zlib压缩之后一般比同样的PNG图片要小。32bit格式png经处理过后的Pixel数据能通过SetPixels直接传递给BitmapData,加载速度非常快。这里发个编解码器。
主要功能有:
- 支持ImageType为1,2,9,10类型的图片。即带调色板,或者直接真彩色的格式都可以解码。同时可以解码RLE的调色板或者真彩格式。
- 支持8bit、16bit、24bit、32bit色深的图片。32bit图片可以支持alpha通道。
- 编码器只支持32bit带Alpha通道格式。并且输出图片按原点在左上角的方式输出。通过这个编码器编码过的图片在使用TgaDecoder解码时候能够直接转换为BitmapData,因此解码速度比其他TGA格式都要快。实际项目中使用时,应该尽量采用这种格式的tga。
- 编码器和解码器都支持处理zlib压缩数据。可通过参数设置
由于有些偏门格式没有找到测试文件,所以测试不完全。
使用方法:
解码:
var dec:TgaDecoder = new TgaDecoder();
dec.Decode( barrData, m_cboxCompressed.selected);
var bmp:Bitmap = new Bitmap( dec.bitmapData);
编码:
var barrData:ByteArray = TgaEncoder.encode( m_bmpData.bitmapData, m_cboxCompressed.selected);
swc和示例项目下载: