Original Post
If you saw the previous thread about minesweeper code injection, this is similar. Minesweeper has a counting timer that increments every second. This timer is controlled through the win32 api. Functions SetTimer and KillTimer control the timer, and after the timeout (1 second here) a WM_TIMER event is generated which is caught by the message queue in minesweeper. So I want to inject simple code to kill the old timer and inject a new timer with the same timerid, so I can effectively change the timeout on the fly without minesweeper knowing. So I need to inject code to call KillTimer then call SetTimer with new paramaters. Blah blah, it ends up being 10 lines or so, whatever, I'll jump to a code cave or something. The question is, where is the best place to jump from, and what is the most elegant way to do this? Is there a way to temporarily hook execution or break from execution from wherever winmine is currently executing, and run my code, then go back? All I can figure is that I can hijack the windows message loop, and use a static variable to make sure it only gets executed once. So I'll insert a jump to code cave like so, then jump back eventually. To line up the instructions I'll probably have to export this whole loop to the cave but I can handle that. here's a paraphrase of the mainloop which seems like a good place to inject
loop:
goto code cave
return from code cave
...
call user32.TranslateAcceleratorW
...
call user32.TranslateMessage
...
call user32.DispatchMessage
...
goto loop So I think I know enough to do all this, but before I bother, I want to make sure it's the best way, because this feels like a huge cludge. So yeah this ended up being a lot of words for not that big of a problem, sorry :( Thanks for your help, Dustin Appendix: the code to reconfigure the timer in case it is relevant (I dont really think it is but I'm a huge reverse engineering noob so I'll post it just in case). Note that it probably doesn't even work but that's something I will work through once I find a place to inject it. cave:
//static bool finished=0;
//if (finished != 0) jmp back_to_mainloop
//finished=1;
push 1 ;TimerID=1
push dword ptr ds:[1005b24] ;hWnd=minesweeper
call dword ptr ds:[user32.KillTimer]
push 0 ;Timerproc=NULL (no callback)
push 7D0 ;2000ms intervals
push 1 ;TimerID=1
push dword ptr ds:[1005B24] ;hWnd=minesweeper
mov dword ptr ds:[1005164],ebx ; don't know why but the original code has this
; don't think it is necessary but i will spend some effort
; tracing ebx and this addr to see if its necessary
call dword ptr ds:[user32.SetTimer]
jmp back_to_mainloop [Edited by - thedustbustr on January 22, 2007 1:43:39 AM]