远程注入代码

   近日在做一软件汉化工作时,由于原软件的标题在程序内部会根据运行状态发生变化,且其中的Tab Contrl控件的标签也是由代码写死的,无法使用资源编辑器进行修改,而且当时没有找到合适的工具来对PE文件进行修改,而且这种方法由于没有做过没有经验,难以保证原有系统的稳定性,所以就采用了在原有程序外面挂接一个程序,来修改原有软件的这部分文字。 

       对于程序的标题栏,在外接程序中使用FindWindowSetWindowText等函数很快就解决问题,但是在修改Tab Control的标签时,却遇上了极大的麻烦,问题描述如下:Tab Control控件本身提供了数种操纵消息,而针对这些消息,微软又提供了一套宏,以方便操作,例如使用TabCtrl_GetItemCount宏来获得Tab Control上的页数,使用TabCtrl_GetItem来获得其中某一页的内容,使用TabCtrl_SetItem来设置某一页的内容。鉴于以上信息,很自然的想到了在外接程序种使用TabCtrl_SetItem来修改Tab Control上某一页的标题,而且很快的,我也在其中写出了代码。然而,问题出现了,该宏并不工作。 

       后来,几经查找,终于找到了原因:外接程序和目标程序,在运行时分别属于两个进程,而TabCtrl_SetItem宏使用SendMessage发送消息,其中一个比较重要的参数是一个TCITEM结构的指针,而此结构种pszText又是一个TCHAR的指针,存储着要设置的字符串资源,然而该TCITEM结构的指针,只在外接程序中有效,到了目标进程中就成了一个野指针。 

       归结起来,这个问题又落到了进程间通信,然而,由于目标程序是已经固定了的,没有源代码,难以修改,所以即使解决了进程间的通信问题,那么问题也仍然难以解决。于是想到了,在目标进程中,注入一段代码,来完成这个工作。首先想到的是DLL注入,但是由于这个问题似乎比较简单,懒得重新开个项目,做个DLL出来,也就是说使用一个比较简单的方法往目标进程中注入一段代码,完成任务即可,于是想到了使用CreateRemoteThread来往目标进程中注入一个线程,在此线程中修改界面的标题,并调用TabCtrl_SetItem等函数来完成任务。 

       于是,很快又参考MSDN中关于CreateRemoteThread函数的规范,写出了线程函数和创建该线程的代码,在VC6中,F5,期望着出现结果,然而,再次,令人失望的是,线程并没有跑起来,使用任务管理器查看,发现目标进程中的线程数并没有任何变化,也就是说,线程创建失败,然而,在外接程序代码中,单步跟踪后,发现线程成功创建,那么,问题出在哪里呢?      

       经过一再的详细阅读MSDN中的说明,忽然发现,原来是远程线程的启动函数的地址出了问题,该函数要求,线程函数的地址要是在目标进程中的地址,而我直接传递的是本地进程中的地址,这样在目标进程中肯定找不到可执行的代码,于是使用VirtuAllocEx函数在目标进程分配控件,使用WriteProcessMemory函数往目标进程拷贝资源,几经周折后,终于让线程跑了起来,并完成了任务。 

       这里是使用CreateRemoteThread函数时的步骤:

    ① 使用VirtualAllocEx函数在目标进程中分配空间,用以容纳线程函数代码。   

    ② 使用WriteProcessMemory函数把本地进程中线程函数的代码拷贝到目标进程中。

    ③ 在目标进程中分配线程参数的空间。

    ④ 把本地进程中设置好的线程参数拷贝到目标仅此中。这里要注意的是,线程参数中最好不要有指针。

    ⑤ 使用CreateRemoteThread函数创建远程线程。

    ⑥ 等待远程线程结束。

    ⑦ 当远程线程结束后,使用VirtualFreeEx函数释放前面所分配的空间。并使用CloseHandle关闭线程句柄。

 

    还有几点值得注意的是:

    ① 在远程进程中使用到的函数,例如SetWindowTextSendMessage等,都需要是目标进程空间中地址。也就是说,要使用LoadLibraryGetProcAddress函数来获得函数的地址。——这里要说明的一点是,LoadLibraryGetProcAddress函数的地址,来自与Kernel32.dll库,而这个库,在Windows平台中,是被映射到相同的地址空间的,所以在本地进程中找到的地址可以在目标进程中使用。

    线程参数中如果涉及到指针,则自己要保证这些指针在目标进程中有效。

    ③ 给代码空间和参数空间分配的空间大小,一定要足够容纳代码和参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值