"Article title": Add "AutoSave" function to XP Notepad in assembly language
"article author": Newjueqi
"Author Email": [Email protected]
"Author QQ": 190678908
"Use tool": OD, Lordpe,exescope
"Operating Platform": XP-SP2
"Author statement": I usually general word processing is using Notepad (with Word seems to be overqualified), the computer has been after the overhaul sometimes will be inexplicably restarted, often rewrite (I often forget to save ^-^), so I would like to add to Notepad similar to Word automatic saving function, to map a convenient. Where mistakes are made please be advised by the heroes!
Specific ideas: In fact, the automatic saving function is the program to save a period of time, and the Notepad program is a save function, so long as the program installed a timer, every time after the simulation click on the "Save Menu", you can achieve automatic saving, the last time to withdraw the timer.
First, add two menu items to Notepad with Exescope "Auto Save", "Close AutoSave", 1:
Figure 1
Where the menu ID for AutoSave is 8, and the menu ID for "Turn off AutoSave" is 13.
After the completion of the menu options are shown in 2:
Figure 2
This modification uses 3 window API functions: SetTimer, KillTimer, SendMessageA, these 3 APIs are not included in the Notepad input table, so use LORDPE to add these 3 APIs to the input table.
Open the Notepad program with LORDPE, select the "..." button of the direction-> input table, then right-click->add Import, you can add a new API to the input list with the 3 interface.
Figure 3
After completion, a new section Slivana4 is added, which is the newly-created IID data, shown in 4
Figure 4
After adding the new API, there is a new problem, that is to determine the new API address, this is in the process of pediy to solve their own, and usually the compiler to help. There are two ways to get an API address:
(1) To view the new IID data directly, after loading the program at the command line to enter D 1013000, 5, as shown:
Figure 5
The correspondence between the IAT and int can be
SetTimer's address =[0101302c]
MessageBoxA's address =[01013030]
KillTimer's address =[01013034]
(2) in OD, press CTRL + N combination key, you can see the location of the API address, 6 of the Red box section is shown
Figure 6
Since pediy usually processes our defined messages before the default window procedure, let's analyze the process of the Notepad program and see the window procedure address of Notepad. As we all know, in a standard window program, you must register the window class, the function prototype is as follows:
ATON registerclassex (CONST wndclassex *ipwcx);
Where Wndclassex *ipwcx is a struct pointer, it is defined as follows:
Wndclassex STRUCT DWORD
cbsize DWORD?
Style DWORD?
Lpfnwndproc DWORD?
Cbclsextra DWORD?
Cbwndextra DWORD?
HInstance DWORD?
Hicon DWORD?
Hcursor DWORD?
Hbrbackground DWORD?
Lpszmenuname DWORD?
lpszClassName DWORD?
HICONSM DWORD?
Wndclassex ENDS
Lpfnwndproc is the address of the window procedure, so we only need to break under RegisterClassEx to know the address of the window process, as shown in OD 7:
Figure 7
As you can see from Figure 7, 1003429 is the address of the system's default window procedure.
Before we start writing code, let's briefly review the Windows procedure functions and general function calls, because we have to have some knowledge of these two aspects in the actual coding process.
The prototype of the window procedure is
Wondowprco proc Hwnd,umsg, WParam, LParam
HWND: A handle to the window that advertises the return value of the CreateWindowEx function gets
Umsg: Identification of the message, usually beginning with the WM
WParam, LParam: Two parameters of the message
When we click on a menu to generate a WM_COMMAND message, for the menu raised by the WM_COMMAND message, the value of LParam is 0,wparam low 16 bits is the command ID, high 16 bits is the notification Code, menu message notification code is 0.
When calling a _stdcall function, the first is the function's arguments in the right-to-left order into the stack, and then the return address of the function into the stack, the general function calls the beginning of the "Push EBP mov ebp,esp" This sentence, so we enter the window process can be similar to Figure 8 of the stack structure
Figure 8
0006fde0/0006fe0c; The value of EBP
0006fde4 |77d18734; return to user32.77d18734, return address value
0006fde8 |00100618; a handle to a window
0006FDEC |00000111, wm_command 16 binary value, can be consulted WinUser.h file for
0006fdf0 |00000008; WParam, the menu ID for auto-save is 8
0006fdf4 |00000000; LParam,
In this context, [ebp+c] is the type of message, [EBP+10] is the wparam parameter, gets the menu's
The ID needs to know the wparam parameter.
There is also a problem to solve, SetTimer and killtimer these two API function parameters must be passed to the window handle as a parameter, but how to find the window handle? We know that after creating a window with the CREATEWINDOWEXW function, a window handle is returned, and in OD, the breakpoint is CREATEWINDOWEXW, and code 9 is interrupted:
Figure 9
From the Red Box section, the window handle is saved at address [1009830].
We want to simulate click on the "Save" menu, you can send a menu message via the Sendmessagew function to the window procedure, the Sendmessagew prototype is as follows:
LRESULT SendMessage (HWND hwnd,uint msg,wparam wparam,lparam iparam);
Parameters:
The HWND is the window handle, which, from the above analysis, is stored on the [1009830] address.
MSG is the type of message to be sent, and the WinUser.h file indicates that WM_COMMAND is 0x111
wparam Low 16 bits is the command ID, high 16 bits is the notification code, the menu message notification code is 0, through the Exescope can be known as "save" the menu ID is 3, so the wparam parameter is 3.
LParam, for menu messages, is 0.
Next is the actual code, I choose to add the code at 0100874F, so the figure 7 red box portion of 1003429 is changed to 0100874F.
Here is the code written
0100874F. A-push EBP
01008750. 8BEC mov ebp, esp
01008752. Pushad
01008753. 817D 0C 11010>cmp dword ptr [Ebp+c], 111; Compare the type of the message to see if it is wm_command, and if it is wm_command then check the wparam parameter to further determine which menu message
0100875A. 0C jnz short 01008768; Check if the message is Wm_timer or wm_close if it is not a WM_COMMAND message
0100875C. 837D cmp DWORD ptr [EBP+10], 8; compare the ID number of the menu to see if the "AutoSave" menu ID
01008760. 1C JE Short 0100877E; no, just jump. Check other message types
01008762. 837D 0D cmp dword ptr [ebp+10], 0D; compare the ID number of the menu to see if the menu ID for "Turn off AutoSave"
01008766. Je short 010087b0; no, just jump. Check other message types
01008768 > 817D 0C 13010>cmp dword ptr [Ebp+c], 113; compare whether the type of message is a WM_TIMER message, Response timer message
0100876F. 5F JE Short 010087d0; no, jump to the end of the function. Clear work
01008771. 837D 0C cmp dword ptr [Ebp+c], 10; Compares whether the type of the message is a WM_CLOSE message, and the timer must be revoked before the retreat
01008775. Je short 010087b0; no, jump to the end of the function. Clear work
01008777 > Popad
01008778. 5D Pop EBP
01008779. ^ E9 abacffff jmp 01003429; jump back to the original Notepad message loop
0100877E > C605 20890001>mov byte ptr [1008920], 1; Mark used auto Save function
01008785. 6A, push 0; /timerproc = NULL
01008787. 60ea0000 Push 0ea60; | Timeout = 60000. Ms
0100878C. 6A Push 1; | Timerid = 1
0100878E. FF35 30980001 push DWORD ptr [1009830]; |hwnd = [1009830], save the address of the window handle after CREATEWINDOWEXW
01008794. FF15 2c300101 call DWORD ptr [<&user32. Settimer>]; /settimer
0100879A. 6A, push 0; /style = mb_ok| Mb_applmodal
0100879C. 00db0001 Push 0100db00; | Title = "Note"
010087A1. 10db0001 Push 0100DB10; | Text = "AutoSave start!"
010087a6. 6A 0; |howner = NULL
010087a8. FF15 30300101 call DWORD ptr [<&user32. messageboxa>>; /messageboxa the auto-save feature is used
010087AE. ^ EB C7 jmp short 01008777; Skip function End Clear
010087b0 > 803D 20890001>cmp byte ptr [1008920], 0; First compare whether the timer has been started
010087b7. ^ The JE short 01008777; skip the function to end the clearance if the timer is not activated.
010087b9. C605 20890001>mov byte ptr [1008920], 0; Restores the boot timer's mark
010087c0. 6A push 1; /timerid = 1
010087c2. FF35 30980001 push DWORD ptr [1009830]; |hwnd, save the address of the window handle after CREATEWINDOWEXW
010087c8. FF15 34300101 call DWORD ptr [<&user32. Killtimer>]; /killtimer, undo Timer
010087CE. ^ EB A7 jmp short 01008777; Skip function End Clear
010087d0 > 6A, push 0; /lparam = 0
010087d2. 6A 3; |wparam = 3, the ID number of the "Save" menu
010087d4. 11010000 Push 111; | Message = Wm_command
010087d9. FF35 30980001 push DWORD ptr [1009830]; |hwnd, save the address of the window handle after CREATEWINDOWEXW
010087DF. FF15 40120001 call DWORD ptr [<&user32. sendmessagew>; /sendmessagew; Send the Click menu "Save" signal to the Notepad window to implement the Save function.
010087E5. ^ EB + jmp short 01008777; Skip function End Clear
Download the modified Notepad address
http://download.csdn.NET/source/1109397
http://blog.csdn.net/newjueqi/article/details/3992084
Use assembly language to add "AutoSave" function to XP Notepad good