hook 了ZWSetSystemTime函数,普通状态下运行正常,但将程序从系统服务模式下重新启动,hook失效,并且导致很多其它应用软件出现运行时216错误,很奇怪。望大侠们指点一下,难道系统服务模式下,函数的入口地址跟普通模式下不一样?我是hook的ntdll.dll里的ZWSetSystemTime啊。我把源码发给大家看一下... library PKTimer;uses
Windows,
Messages,
untAPIHOOK in 'untAPIHOOK.pas';const MapName='PKTimer';
UM_TIMECHANGE=WM_USER+1001;
type
TShareMem=record
HwndParent:Cardinal;
end;
PShareMem=^TShareMem; TMySetSystemTime=function(_oldtime:PLargeInteger;_newtime:PLargeInteger):BOOL;stdcall;var
hk_SetSystemTime:TAPIHook;
msghk:HHOOK;
hMap:Cardinal;
dtp:PShareMem;
LastTime:Cardinal;
//--------------------------
function MySetSystemTime(_oldtime:PLargeInteger;_newtime:PLargeInteger):BOOL;stdcall;
var
dt:TCopyDataStruct;
bf:array [0..MAX_PATH] of Char;
begin
if GetTickCount-LastTime >50 then begin
GetModuleFileName(0,bf,MAX_PATH);
dt.cbData:=MAX_PATH;
dt.lpData:=@bf;
dt.dwData:=2007;
//if SendMessage(dtp^.HwndParent,UM_TIMECHANGE,dt.cbData,LongInt(@dt))=1 then begin
if SendMessage(dtp^.HwndParent,UM_TIMECHANGE,0,0)=1 then begin
hk_SetSystemTime.FindOn;;
Result:=TMySetSystemTime(hk_SetSystemTime.OldAddr)(_oldtime,_newtime);
hk_SetSystemTime.FindOff;
end else begin
Result:=false;
end;
end else Result:=false;
LastTime:=GetTickCount;
end;function HookProc(nCode,wParam,lParam:Cardinal):Cardinal;stdcall;
begin
Result:=CallNextHookEx(msghk,nCode,wParam,lParam);
end;
procedure LockTime(HwndParent:Cardinal;ALock:BOOL);stdcall;
begin
dtp^.HwndParent:=HwndParent;
if ALock then
msghk:=SetWindowsHookEx(WH_GETMESSAGE,@HookProc,HInstance,0)
else
UnhookWindowsHookEx(msghk);
end;
//--------------------------
procedure DllMain(nTag:Cardinal);
begin
case nTag of
DLL_PROCESS_ATTACH:begin
hMap:=OpenFileMapping(FILE_MAP_ALL_ACCESS,false,MapName);
if hMap=0 then hMap:=CreateFileMapping(THandle(-1),nil,PAGE_READWRITE,0,SizeOf(TShareMem),MapName);
dtp:=MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);
if dtp=nil then Exit; hk_SetSystemTime:=TAPIHook.Create('ntdll.dll','ZwSetSystemTime',@MySetSystemTime);
hk_SetSystemTime.HookAPI;
end;
DLL_PROCESS_DETACH:begin
hk_SetSystemTime.UnHookAPI;
hk_SetSystemTime.Free; UnmapViewOfFile(dtp);
CloseHandle(hMap);
end;
end;
end;
//--------------------------
exports
LockTime;
begin
DllProc:=@DllMain;
DllMain(DLL_PROCESS_ATTACH);
end.procedure LockTime(HwndParent: Cardinal; ALock: BOOL); stdcall; external 'PKTimer.dll';然后在需要的地方调用
LockTime(Handle, true);最后当有ZWSetSystemTime被拦截时,发送UM_TIMECHANGE消息至HWndParnet,在主窗口处理该消息Hook的实现部分constructor TAPIHook.Create(ModuleName:PChar;OldFunName:PChar;NewFun:Pointer);
begin
Self.F_ModuleName:=ModuleName;
Self.F_OldFunName:=OldFunName;
Self.F_NewFun:=NewFun;
end;procedure TAPIHook.HookAPI;
var
DLLModule : THandle;
begin
Self.F_ProcessHandle := GetCurrentProcess;
DLLModule := LoadLibrary(Self.F_ModuleName);
OldAddr := GetProcAddress(DLLModule, Self.F_OldFunName); //取得API地址 JmpCode.JmpCode := $B8;
JmpCode.MovEAX[0] := $FF;
JmpCode.MovEAX[1] := $E0;
JmpCode.MovEAX[2] := 0; ReadProcessMemory(Self.F_ProcessHandle, OldAddr, @Oldproc[0], 8, dwSize);
JmpCode.Address := Self.F_NewFun;
WriteProcessMemory(Self.F_ProcessHandle, OldAddr, @JmpCode, 8, dwSize); //修改Send入口end;
Windows,
Messages,
untAPIHOOK in 'untAPIHOOK.pas';const MapName='PKTimer';
UM_TIMECHANGE=WM_USER+1001;
type
TShareMem=record
HwndParent:Cardinal;
end;
PShareMem=^TShareMem; TMySetSystemTime=function(_oldtime:PLargeInteger;_newtime:PLargeInteger):BOOL;stdcall;var
hk_SetSystemTime:TAPIHook;
msghk:HHOOK;
hMap:Cardinal;
dtp:PShareMem;
LastTime:Cardinal;
//--------------------------
function MySetSystemTime(_oldtime:PLargeInteger;_newtime:PLargeInteger):BOOL;stdcall;
var
dt:TCopyDataStruct;
bf:array [0..MAX_PATH] of Char;
begin
if GetTickCount-LastTime >50 then begin
GetModuleFileName(0,bf,MAX_PATH);
dt.cbData:=MAX_PATH;
dt.lpData:=@bf;
dt.dwData:=2007;
//if SendMessage(dtp^.HwndParent,UM_TIMECHANGE,dt.cbData,LongInt(@dt))=1 then begin
if SendMessage(dtp^.HwndParent,UM_TIMECHANGE,0,0)=1 then begin
hk_SetSystemTime.FindOn;;
Result:=TMySetSystemTime(hk_SetSystemTime.OldAddr)(_oldtime,_newtime);
hk_SetSystemTime.FindOff;
end else begin
Result:=false;
end;
end else Result:=false;
LastTime:=GetTickCount;
end;function HookProc(nCode,wParam,lParam:Cardinal):Cardinal;stdcall;
begin
Result:=CallNextHookEx(msghk,nCode,wParam,lParam);
end;
procedure LockTime(HwndParent:Cardinal;ALock:BOOL);stdcall;
begin
dtp^.HwndParent:=HwndParent;
if ALock then
msghk:=SetWindowsHookEx(WH_GETMESSAGE,@HookProc,HInstance,0)
else
UnhookWindowsHookEx(msghk);
end;
//--------------------------
procedure DllMain(nTag:Cardinal);
begin
case nTag of
DLL_PROCESS_ATTACH:begin
hMap:=OpenFileMapping(FILE_MAP_ALL_ACCESS,false,MapName);
if hMap=0 then hMap:=CreateFileMapping(THandle(-1),nil,PAGE_READWRITE,0,SizeOf(TShareMem),MapName);
dtp:=MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);
if dtp=nil then Exit; hk_SetSystemTime:=TAPIHook.Create('ntdll.dll','ZwSetSystemTime',@MySetSystemTime);
hk_SetSystemTime.HookAPI;
end;
DLL_PROCESS_DETACH:begin
hk_SetSystemTime.UnHookAPI;
hk_SetSystemTime.Free; UnmapViewOfFile(dtp);
CloseHandle(hMap);
end;
end;
end;
//--------------------------
exports
LockTime;
begin
DllProc:=@DllMain;
DllMain(DLL_PROCESS_ATTACH);
end.procedure LockTime(HwndParent: Cardinal; ALock: BOOL); stdcall; external 'PKTimer.dll';然后在需要的地方调用
LockTime(Handle, true);最后当有ZWSetSystemTime被拦截时,发送UM_TIMECHANGE消息至HWndParnet,在主窗口处理该消息Hook的实现部分constructor TAPIHook.Create(ModuleName:PChar;OldFunName:PChar;NewFun:Pointer);
begin
Self.F_ModuleName:=ModuleName;
Self.F_OldFunName:=OldFunName;
Self.F_NewFun:=NewFun;
end;procedure TAPIHook.HookAPI;
var
DLLModule : THandle;
begin
Self.F_ProcessHandle := GetCurrentProcess;
DLLModule := LoadLibrary(Self.F_ModuleName);
OldAddr := GetProcAddress(DLLModule, Self.F_OldFunName); //取得API地址 JmpCode.JmpCode := $B8;
JmpCode.MovEAX[0] := $FF;
JmpCode.MovEAX[1] := $E0;
JmpCode.MovEAX[2] := 0; ReadProcessMemory(Self.F_ProcessHandle, OldAddr, @Oldproc[0], 8, dwSize);
JmpCode.Address := Self.F_NewFun;
WriteProcessMemory(Self.F_ProcessHandle, OldAddr, @JmpCode, 8, dwSize); //修改Send入口end;
解决方案 »
- 用DELPHI怎么连接internet上的SQL server
- 好奇的人进来领分(快毕业了,分多了,为兄弟们发工资啦)
- Paradox中存放.jpg图片???
- 大家来讨论,如何在代码编辑器中自动生成函数的注释
- 请帮我看看
- Delphi爱好者 qq:32443311 愿与所有的delphi爱好者共同进步
- 请问高手们如何用delphi做一个远程启动的程序,也就是说在一台计算机上启动另一台计算机中的程序。
- 做个调查,有多少人学习了认证? 北大清鸟的ACCP怎么样, 我想去系统学习.不知道好不好.提出忠告意见必给多分!
- 很简单的一个问题!
- 如何修复DB表?急急急………
- fastreport 4.0 调用函数报错的问题?
- 服务启动问题(请僵哥解答,也欢迎其它高手)
另外,在Vista系统中,服务进程与用户进程不能通过DLL共享内存,XP系统好象没有这问题。
某人很生气,后果很严重……开个玩笑……
加载方式是怎么样的?按理说没用驱动,应该不会存在太大问题……
LockTime(Handle, true); 最后当有ZWSetSystemTime被拦截时,发送UM_TIMECHANGE消息至HWndParnet,在主窗口处理该消息