能力值:
( LV2,RANK:10 )
2 楼
拦这个要用消息断点。。。WM_TIMER,但是OD支持消息断点吗???
还是从SetTimer入手吧。。
UINT SetTimer(
HWND hWnd, // handle of window for timer messages
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procedure
);
SetTimer会传入要处理消息的地址。。。呵呵,有门儿了吧。
能力值:
( LV2,RANK:10 )
3 楼
但是SetTimer的时候 TIMEPORC 是 0。
能力值:
( LV4,RANK:50 )
4 楼
你可以参考下面的资料
方法一 让Windows把WM_TIMER消息发送到应用程序的正常窗口消息处理程序中,SetTimer呼叫如下所示:
SetTimer (hwnd, 1, uiMsecInterval, NULL) ;
方法二 设定定时器的第一种方法是把WM_TIMER消息发送到通常的窗口消息处理程序,而第二种方法是让Windows直接将定时器消息发送给您程序的另一个函数。
接收这些定时器消息的函数被称为「callback」函数,这是一个在您的程序之中但是由Windows呼叫的函数。您先告诉Windows此函数的地址,然后Windows呼叫此函数。这看起来也很熟悉,因为程序的窗口消息处理程序实际上也是一种callback函数。当注册窗口类别时,要将函数的地址告诉Windows,当发送消息给程序时,Windows会呼叫此函数。
VOID CALLBACK TimerProc ( HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
处理WM_TIMER消息
}
TimerProc的参数hwnd是在呼叫SetTimer时指定的窗口句柄。Windows只把WM_TIMER消息送给TimerProc,因此消息参数总是等于WM_TIMER。iTimerID值是定时器ID,dwTimer值是与从GetTickCount函数的传回值相容的值。这是自Windows启动后所经过的毫秒数。
用第一种方法设定定时器时要求下面格式的SetTimer呼叫:
SetTimer (hwnd, iTimerID, iMsecInterval, NULL) ;//****************
您使用callback函数处理WM_TIMER消息时,SetTimer的第四个参数由callback函数的地址取代,如下所示:
SetTimer (hwnd, iTimerID, iMsecInterval, TimerProc) ;//**************** 设定定时器的第三种方法类似于第二种方法,只是传递给SetTimer的hwnd参数被设定为NULL,并且第二个参数(通常为定时器ID)被忽略了,最后,此函数传回定时器ID:
iTimerID = SetTimer (NULL, 0, wMsecInterval, TimerProc) ;:)
能力值:
(RANK:10 )
5 楼
最初由 云重 发布 你可以参考下面的资料 方法一 让Windows把WM_TIMER消息发送到应用程序的正常窗口消息处理程序中,SetTimer呼叫如下所示: ........
支持!
能力值:
( LV2,RANK:10 )
6 楼
根据3楼的说法,
但是SetTimer的时候 TIMEPORC 是 0。
那程序应该是Delphi的吧,Delphi 在处理Timer时,SetTimer传的TimeProc 是0,因为Delphi不通过回调函数的方式,而是通过消息实现。
constructor TTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := True;
FInterval := 1000;
FWindowHandle := AllocateHWnd(WndProc);
end;
其中AllocateHWnd(WndProc)就会产生一个大小为0的窗口,并将WndProc作为其窗口过程,来处理消息。
再看其窗口过程:
procedure TTimer.WndProc(var Msg: TMessage);
begin
with Msg do
if Msg = WM_TIMER then
try
Timer;
except
Application.HandleException(Self);
end
else
Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
end;
里边只做了对WM_TIMER的比较,所以就有希望了。
这个过程反汇编后就是:
这是编译时,选择“Build with runtime package”的方式:
4007A6A8 V> 55 push ebp
4007A6A9 8BEC mov ebp,esp
4007A6AB 51 push ecx
4007A6AC 53 push ebx
4007A6AD 56 push esi
4007A6AE 57 push edi
4007A6AF 8BDA mov ebx,edx
4007A6B1 8945 FC mov dword ptr ss:[ebp-4],eax
4007A6B4 8B33 mov esi,dword ptr ds:[ebx]
4007A6B6 81FE 13010000 cmp esi,113 //if Msg = WM_TIMER then
4007A6BC 75 3F jnz short Vcl50.4007A6FD
4007A6BE 33C0 xor eax,eax
4007A6C0 55 push ebp
4007A6C1 68 E2A60740 push Vcl50.4007A6E2
4007A6C6 64:FF30 push dword ptr fs:[eax]
4007A6C9 64:8920 mov dword ptr fs:[eax],esp
4007A6CC 8B45 FC mov eax,dword ptr ss:[ebp-4]
4007A6CF 66:BB F0FF mov bx,0FFF0
4007A6D3 E8 D495F8FF call Vcl50.System::CallDynaInst
4007A6D8 33C0 xor eax,eax
4007A6DA 5A pop edx
4007A6DB 59 pop ecx
4007A6DC 59 pop ecx
4007A6DD 64:8910 mov dword ptr fs:[eax],edx
4007A6E0 EB 33 jmp short Vcl50.4007A715
4007A6E2 ^ E9 BD98F8FF jmp Vcl50.System::HandleAnyException
4007A6E7 A1 E0EB1540 mov eax,dword ptr ds:[4015EBE0]
4007A6EC 8B00 mov eax,dword ptr ds:[eax]
4007A6EE 8B55 FC mov edx,dword ptr ss:[ebp-4]
4007A6F1 E8 1A06FEFF call Vcl50.Forms::TApplication::HandleException
4007A6F6 E8 C59CF8FF call Vcl50.System::DoneExcept
4007A6FB EB 18 jmp short Vcl50.4007A715
4007A6FD 8B43 08 mov eax,dword ptr ds:[ebx+8]
4007A700 50 push eax
4007A701 8B43 04 mov eax,dword ptr ds:[ebx+4]
4007A704 50 push eax
4007A705 56 push esi
4007A706 8B45 FC mov eax,dword ptr ss:[ebp-4]
4007A709 8B40 28 mov eax,dword ptr ds:[eax+28]
4007A70C 50 push eax
4007A70D E8 7A07F9FF call <jmp.&user32.DefWindowProcA>
4007A712 8943 0C mov dword ptr ds:[ebx+C],eax
4007A715 5F pop edi
4007A716 5E pop esi
4007A717 5B pop ebx
4007A718 59 pop ecx
4007A719 5D pop ebp
4007A71A C3 retn
如果不选择则是:
0043EECA . 57 push edi
0043EECB . 8BDA mov ebx,edx
0043EECD . 8945 FC mov dword ptr ss:[ebp-4],eax
0043EED0 . 8B33 mov esi,dword ptr ds:[ebx]
0043EED2 . 81FE 13010000 cmp esi,113 //if Msg = WM_TIMER then
0043EED8 . 75 3F jnz short tm1.0043EF19
0043EEDA . 33C0 xor eax,eax
呵呵,看出什么没? 再告诉你:WM_TIMER 定义为:$0113
所以只要在代码中查找命令:
cmp esi,113 就可以找到onTimer入口了。
需要注意的是:如果Build with runtime package时,要到VCLXX.bpl的模块中找。
能力值:
( LV2,RANK:10 )
7 楼
谢谢各位了!
能力值:
(RANK:10 )
8 楼
感谢分享!!!