S
SNKoala
Unregistered / Unconfirmed
GUEST, unregistred user!
Windows9x系列,内存管理采用段页式。代码段选择子(CS)和数据段选择子(DS等)指
向不同的起点。整个4G地址空间被分为两部分,一部分是系统区,一部分是应用程序区。
应用程序的代码,数据等都在应用程序地址区内。而应用程序使用的API的DLL都映射到
系统区。在Windows 9x中,系统区的虚地址--物理地址映像对每一个应用都是一样的,
因此在Windows 9x中,可以通过在这片地址中分配内存,在各个程序中共享。
针对这样的情况,API Hook可以这样实现:
1。为了读写代码段的内存,必须给代码段的选择子分配一个指向同一个地方但是有写权
限的数据段选择子。代码看起来像这样:
selCS = FP_SEG((void FAR *)ExtTextOut);//取ExtTextOut在得段的选择子
selDS = AllocCStoDSAlias(selCS ) ; //分配可写的选择子
2。保存原来的数据(就是API的代码)
3。在开始的地方写上一个长跳转指令,跳到自己的代码。释放选择子。
(自己的代码必须是在DLL中的)
4。在发生调用时,恢复原来的代码,进行实际调用。
5。重新安装上钩子。
lpCode = MK_FP ( selDS , FP_OFF( (void FAR * ) ExtTextOut ) ) ;
_fmemcpy( OldCode , lpCode , 5 );
lpCode[0] = 0xEA ;
lpJmp = (char FAR * )&Jmp2Me;
lpCode[1]=lpJmp[0];
lpCode[2]=lpJmp[1];
lpCode[3]=lpJmp[2];
lpCode[4]=lpJmp[3];
FreeSelector(selDS );
完整例子在:ftp://ftp.cs.pku.edu.cn/ProgramSource/DelphiCom/GUIhook95.zip
(注:我也正在研究,代码只是将就能看懂,还有很多问题,如多进程/线程同时操作
怎么办等,希望大家能跟我探讨。)
向不同的起点。整个4G地址空间被分为两部分,一部分是系统区,一部分是应用程序区。
应用程序的代码,数据等都在应用程序地址区内。而应用程序使用的API的DLL都映射到
系统区。在Windows 9x中,系统区的虚地址--物理地址映像对每一个应用都是一样的,
因此在Windows 9x中,可以通过在这片地址中分配内存,在各个程序中共享。
针对这样的情况,API Hook可以这样实现:
1。为了读写代码段的内存,必须给代码段的选择子分配一个指向同一个地方但是有写权
限的数据段选择子。代码看起来像这样:
selCS = FP_SEG((void FAR *)ExtTextOut);//取ExtTextOut在得段的选择子
selDS = AllocCStoDSAlias(selCS ) ; //分配可写的选择子
2。保存原来的数据(就是API的代码)
3。在开始的地方写上一个长跳转指令,跳到自己的代码。释放选择子。
(自己的代码必须是在DLL中的)
4。在发生调用时,恢复原来的代码,进行实际调用。
5。重新安装上钩子。
lpCode = MK_FP ( selDS , FP_OFF( (void FAR * ) ExtTextOut ) ) ;
_fmemcpy( OldCode , lpCode , 5 );
lpCode[0] = 0xEA ;
lpJmp = (char FAR * )&Jmp2Me;
lpCode[1]=lpJmp[0];
lpCode[2]=lpJmp[1];
lpCode[3]=lpJmp[2];
lpCode[4]=lpJmp[3];
FreeSelector(selDS );
完整例子在:ftp://ftp.cs.pku.edu.cn/ProgramSource/DelphiCom/GUIhook95.zip
(注:我也正在研究,代码只是将就能看懂,还有很多问题,如多进程/线程同时操作
怎么办等,希望大家能跟我探讨。)