Nebob
January 10th, 2003, 00:10
I have a simple program that I want to modify. When this program starts, it displays a window with a few buttons. The user must click one of these buttons, at which point stuff happens. I want to modify the program so that the button is automatically "clicked", and user intervention is not required. I'm having a great deal of trouble coming up with the right method to achieve this.
In winmain, I have code that calls:
GetSystemInfo
FindWindowA
SetForegroundWindow
and so on when the program first starts. When this is done, the program calls "init_main_wnd":
call init_main_wnd
If this fails, we do a whole bunch of error checks to find out what wen't wrong (can't register window class, etc) and bail out.
Now at the beginning of init_main_wnd, we have:
And so on. Later, we have:
Which is important, since this is our message pump.
In msg_handler, we have a long series of:
cmp [ebp+Msg_], some_msg_here
jxx handler
Then later, we have:
.text:00416D9F cmp [ebp+Msg_], WM_COMMAND
.text:00416DA9 jz button
This is the code that compares the msg with 111h and handles the case for *any* button. Because there is more than just one, when we follow the jz, we have:
Here we finally find the handler we need, "start_btn".
"start_btn" jumps to a chunk of code that creates a new thread:
At offset "cthread", we have the proc that calls the actual computation routines for the thread.
From there on, we get into FP code which doesn't interest us.
I've tried patching absolute jumps to various pieces of code at various locations in order to achieve this result, but I've been unsuccessful -- my program always crashes or errors out. What is the proper method to achieve something like this, and where should I put it?
In winmain, I have code that calls:
GetSystemInfo
FindWindowA
SetForegroundWindow
and so on when the program first starts. When this is done, the program calls "init_main_wnd":
call init_main_wnd
If this fails, we do a whole bunch of error checks to find out what wen't wrong (can't register window class, etc) and bail out.
Now at the beginning of init_main_wnd, we have:
Code:
.text:00415C10 push ebp
.text:00415C11 mov ebp, esp
.text:00415C13 sub esp, 30h
.text:00415C16 mov [ebp+WNDCLASSEX.cbClsExtra], 0
.text:00415C1D mov [ebp+WNDCLASSEX.cbSize], 30h
.text:00415C24 mov [ebp+WNDCLASSEX.cbWndExtra], 0
.text:00415C2B push 0Fh ; nIndex
.text:00415C2D call GetSysColorBrush
.text:00415C33 mov [ebp+WNDCLASSEX.hbrBackground], eax
.text:00415C36 push 7F00h ; lpCursorName
.text:00415C3B push 0 ; hInstance
.text:00415C3D call LoadCursorA
.
.
.
And so on. Later, we have:
Code:
.text:00415C79 mov [ebp+WNDCLASSEX.hInstance], edx
.text:00415C7C mov [ebp+WNDCLASSEX.lpfnWndProc], offset msg_handler
Which is important, since this is our message pump.
In msg_handler, we have a long series of:
cmp [ebp+Msg_], some_msg_here
jxx handler
Then later, we have:
.text:00416D9F cmp [ebp+Msg_], WM_COMMAND
.text:00416DA9 jz button
This is the code that compares the msg with 111h and handles the case for *any* button. Because there is more than just one, when we follow the jz, we have:
Code:
.text:00416E71 button: ; CODE XREF: msg_handler+49j
.text:00416E71 mov ecx, ds:lpParameter
.text:00416E77 mov edx, [ebp+arg_C]
.text:00416E7A cmp edx, [ecx+320h]
.text:00416E80 jnz usrname_btn
.text:00416E86 cmp ds:dword_4377D8, 0
.text:00416E8D jnz stop_btn
.text:00416E93 mov [ebp+var_4], 0
.text:00416E9A jmp short start_btn
Here we finally find the handler we need, "start_btn".
"start_btn" jumps to a chunk of code that creates a new thread:
Code:
.text:00416ECD push ecx ; lpThreadId
.text:00416ECE push 0 ; dwCreationFlags
.text:00416ED0 mov edx, ds:lpParameter
.text:00416ED6 push edx ; lpParameter
.text:00416ED7 push offset cthread ; lpStartAddress
.text:00416EDC push 0 ; dwStackSize
.text:00416EDE push 0 ; lpThreadAttributes
.text:00416EE0 call CreateThread
At offset "cthread", we have the proc that calls the actual computation routines for the thread.
Code:
.text:00417B20 cthread proc near ; DATA XREF: msg_handler+177o
.text:00417B20
.text:00417B20 arg_0 = dword ptr 8
.text:00417B20
.text:00417B20 push ebp
.text:00417B21 mov ebp, esp
.text:00417B23 mov eax, [ebp+arg_0]
.text:00417B26 push eax
.text:00417B27 call sub_401B10
.text:00417B2C add esp, 4
.text:00417B2F xor eax, eax
.text:00417B31 pop ebp
.text:00417B32 retn 4
.text:00417B32 cthread endp
From there on, we get into FP code which doesn't interest us.
I've tried patching absolute jumps to various pieces of code at various locations in order to achieve this result, but I've been unsuccessful -- my program always crashes or errors out. What is the proper method to achieve something like this, and where should I put it?