In Windows, the program prevents multiple common methods:
1) Use the findwindow API function.
You can query the window title (or/and Class Name) to determine whether the program is running. If it is found, it indicates that the program is running, and you can exit the program to achieve the effect of not repeating the operation; otherwise, it indicates that the program is running for the first time.
This method is not applicable to situations where the program title is dynamically changed and the system runs a program with the same title (or/and class name)
2) mutex/event/semaphore
Determine whether the program is running by means of mutex objects, semaphores, events, and other thread synchronization objects. The most common functions are: createmutexa (Note: QQ Hall and QQ game hall use this method to limit the opening of multiple programs)
3) file ing)
By placing program instance information in a cross-process memory ing file, you can also control multiple programs.
4) DLL global share zone
The DLL global shared area is initialized only once when it is mapped to the address space of each process. It is the first time that it is loaded by windows. Therefore, you can use the data in this area to limit the number of programs.
5) global atom
Add a specific string to the global atom table through globaladdatom. when running the program, check whether the string exists to restrict the program from opening more. (This atom will not be released automatically. You must call globaldeleteatom to release atom before exiting the program)
6) Check window properties
Add some data to the property list of the specified window through setprop. during the running of the program, enumerate the window and check whether the data exists to limit the extra opening.
The above lists the most common methods. N options can be selected for specific applications, or multiple methods can be used to limit them.
As mentioned above, qqt uses the createmutex function to limit multiple open operations. How do I know that this function is used to limit it?
The answer is the tracing program, which method is used to find the program to limit. For example, first check whether createmutex is used to limit the number. If not, then check whether findwindow is used, and so on until the method is found. Of course, some programs also use a variety of methods to restrict multiple open methods. The method is the same, but it is only troublesome.
The following describes how to use the createmutex function to limit multiple open methods:
The createmutex function declaration is as follows (For details, refer to relevant materials, such as msdn)
Handle createmutex (
Lpsecurity_attributes lpmutexattributes, // pointer to security attributes
Bool binitialowner, // flag for Initial ownership
Lptstr lpname // pointer to mutex-Object Name
);
The following is a typical Delphi code that uses the createmutex function to limit multi-open
Hmutex: = createmutex (nil, true, 'qqtang'); // create a mutex
// Call failed? Already exists?
If (hmutex = 0) or (getlasterror = error_already_exists) then
Begin
// Getlasterror returns error_already_exists during the second (or later) Running of the program, indicating that the mutex already exists
// You can write exit code here
End;
This code first calls the createmutex function to create a mutex object named qqtang. If the createmutex function fails to be called (hmutex = nil) or the mutex object already exists (getlasterror = error_already_exists), the program exits.
Now, after understanding the above content, let's proceed to the actual modification:
Download ollydbg V1.1 and decompress it to any directory.
Start ollydbg, open the core. dll file under the qqt directory, and press [Yes] to load the DLL file.
Press Ctrl + n to open the API call list, find createmutexa, and press Enter. In the displayed window, double-click the first line to go to the CPU window. The disassembly code is as follows:
10002fb9. 51 push ECx;/mutexname = "qqtang"
10002fba. 6a 01 Push 1; | initialowner = true
10002fbc. 6a 00 push 0; | psecurity = NULL
10002fbe. ff15 60e40010 call dword ptr [<& kernel32.createmutexa>]; \ createmutexa creates mutex
10002fc4. 8b95 d4feffff mov edX, dword ptr [ebp-12C]
10002fca. 8902 mov dword ptr [edX], eax
10002fcc. 8b85 d4feffff mov eax, dword ptr [ebp-12C]
10002fd2. 8338 00 cmp dword ptr [eax], 0; check whether the createmutexa function fails to be called
10002fd5. 0f84 cd000000 je core.100030a8; change je to JMP.
10002fdb. ff15 5ce40010 call dword ptr [<& kernel32.getlasterror>]; [getlasterror
10002fe1. 3D b7000000 CMP eax, 0b7; check whether the object exists
10002fe6. 0f85 bc000000 jnz core.100030a8; (you can also change jnz to JMP here)
10002fec. 8b8d d4feffff mov ECx, dword ptr [ebp-12C]
10002ff2. c701 00000000 mov dword ptr [ECx], 0
10002ff8. 6a 00 push 0;/Title = NULL
10002ffa. 68 5cc60010 push core.1000c65c; | class = "qqtangwinclass"
10002fff. 6a 00 push 0; | hafterwnd = NULL
10003001. 6a 00 push 0; | hparent = NULL
10003003. ff15 40e70010 call dword ptr [<& user32.find1_wexa>]; \ find1_wexa find qqt window
Select this line:
10002fd5. 0f84 cd000000 je core.100030a8
Then press the space, change "Je 100030a8" to "JMP 100030a8" in the pop-up window, and press [assemble].
Right-click the CPU window, select copy to executable file-all changes from the shortcut menu, and select [copy all]. Right-click the pop-up window and choose Save file to save.
Do you think the above changes are troublesome? Haha, it is better to teach people to fish than to teach them to fish. The above shows you why you want to modify it like this. What is the principle of modification? After you understand the principle of modification, you can modify the new version by yourself.