工作关系,想HOOK并修改一些API,使得不支持某些设备的第三方工具可以正常运行,因此花时间写了这么个工具。比如ReadFile时,某些设备不支持指定的缓存大小(如512KB),可以HOOK ReadFile,把缓存大小修改为更小,可能ReadFile就能正常工作,第三方工具也能正常使用。其实,只是想借工作这个契机,学习远程线程注入和HOOK API。工作上测试的设备和第三方工具运行在64位机上,还没有时间在64位机上修改并编译。
运行DEMO说明:
首先进入TestExe目录,打开MFCDialogApplication.exe,8个按钮分别简单的调用8个API,可一一点击查看效果,标题栏显示进程ID:
打开DllImport.exe,弹出Console,以下显示的是我输入并HOOK完的界面:
首先输入需要HOOK的进程ID,这里输入对话框进程ID12600。然后提示选择需HOOK的API,每个API有FLAG值,占一位,可以用位组合,这里输入511,即9个API都需HOOK。然后选择是HOOK还是UNHOOK,这里当然输入1。然后这个程序向对话框程序注入线程,调用DllExport.dll,DllExport.dll中HOOK这9个API。结果全部成功,见上图。HOOK对话框后,会在对话框进程中弹出一个Console窗口,用以显示相关信息,见下图:
然后在对话框上一一点击各个按钮,并随时查看弹出的Console窗口中内容,单击完后,见下图:
每点击一个按钮后,在Console中会显示相关信息。这些信息是HOOK时打印的,我只设置了打印简单的信息。还要注意,HOOK
MessageBoxA和MessageBoxW时,改变了弹出消息框的标题、文字等。
然后再打开DllImport.exe,把HOOK的API还原,并从对话框进程中卸载DllExport.dll,输入顺序与HOOK一致,只是第三步时需指定0,见下图:
UNHOOK API时我选择的全部还原。完后,9个API不再被HOOK,正常执行,之前显示信息的Console关闭,对话框正常运行。所有API UNHOOK后,DllExport.dll被卸载,可改名、删除等。此时,再点击对话框按钮,就不再有任何显示显示。注意点击两个MessageBox后,消息框的标题与文字。
一些表单验证需要返回json数据,php的json_encode函数只支持utf-8编码,无奈只得iconv了,需要达到的效果是GBK数组转换成utf-8数组传给json_encode函数。
最开始的思路,将数组序列化后用iconv函数转换编码,之后再反序列化,代码如下:
unserialize(iconv('gbk','utf-8',serialize($array)));
得到的结果是空白,后来想起来配置文件里设置了默认编码 ini_set('default_charset', 'gbk'); 这样用gbk反序列化utf-8的字符串肯定不好用了,此处在序列化和反序列化之间加个ini_set('default_charset', 'utf-8'); 应该也是可以的,但这么弄总觉得有点别扭,因为是全局的编码设置,很容易导致其他地方的编码问题,比如数据库操作。那么换个思路,用构建数组原型的序列化方法,借助var_export函数,最终函数如下:
function array_iconv($in_charset,$out_charset,$arr){ return eval('return '.iconv($in_charset,$out_charset,var_export($arr,true).';')); }
原理很简单 var_export设置第二个参数为true,返回数组原型字符串,将字符串转换为utf-8编码,之后再用eval来执行返回(类似匿名函数?),至此完美解决问题。
后续:后来在网上搜了下资料,看有没有更好的方法,找到的都大同小异,都是利用递归调用iconv的方式,如果数组元素过多或者维数多一些,性能上肯定不怎么样了,更好的是原生代码的方式,不需要考虑是N维数组还是关联数组,一切都已经自动完成,保证数组转换前后数据一致。从代码的长短以及循环和原生方法的比较上,相信大家已经有了选择。
在Eclipse中关联源代码
在使用Eclipse的时候,为了查看一些Java代码的具体实现,通常需要查看一些源代码,但是有些时候都是我们使用到了某个类,想查看它的源代码的时候,才去关联源代码,而我一直想知道这么一个问题:当我在没有想看源代码之前,将自己的Eclipse已经关联源代码了,该怎么设置,现在终于知道了,所以根据自己所学的知识,分享给大家。
首先说一下常规的关联源代码的方式,当我们想查看HashMap源代码的时候,由于没有关联源代码变会出现如下页面:
在该页面中可以很清楚的看到没有发现源代码,所以单击上方的“Attach Source”按钮,打开如下页面:
由于没有关联源代码,所以上方的“Location path”处是空的,单击“External File”按钮,选择我们的Java的源代码压缩文件src.zip,在“Location path”处就可以看到自己的源代码的路径,单击OK按钮,即可以看到HashMap的源代码了。如下图所示:
接下来说一下如何在Eclipse中设置关联源代码。
从下图中,可以看到,当前的rt.jar包没有关联源代码,既然是jar包没有关联,那么在添加jar包的地方,应该有设置关联源代码的地方吧!确实是的。那么我们便会想到了构建路径,所以打开构建路径。
在构建路径中选择“Libraties”选项卡,展开rt.jar选项,可以清楚的看到第一项的“Source attachment”为空,所以选择右键如图所示右边的Edit按钮,如图所示:
当单击了该按钮,便又会出现了如下这个界面,所以我们按照如上的操作便可以关联源代码了。
或者是在如下的窗口中设置,如图所示:
上边的图应该不是很陌生吧!当我们在Eclipse中添加一个JRE的时候,也是可以关联源代码的。有些时候我们不想使用Eclipse的JRE,而是想使用我们自己的JRE,便会打开上面的窗口,选择对应的jar包,然后选择右边的“Source Attachment”选项。如图所示:
之后,便再次出现了如下的窗口:
至此,我们的Eclipse关联源代码就结束了,对于MyEclipse我想也应该是这样的。