Suppose you have a windows' program that doesn't allow multiple instances of it running at the same time ( like the program attached to this post: JustOne.exe ), but for some reason you want two or more instances. A common approach to set this limitation it is to use a _named_ kernel object ( if you want more details about kernel object:
http://msdn2.microsoft.com/en-us/librar ... 85%29.aspx ).
To create a kernel object we can use, for example:
- CreateMailslot( )
- CreateMutex( )
- CreateSemaphore( )
and so on..
Let's see a pratical example, consider the following function:
Code:
//This function tries to set a lock
int setLock()
{
//Creates a kernel object with name: {LuigiLikesCookies}"
//and sets LastError
HANDLE h = CreateMutex(NULL, false, L"{LuigiLikesCookies}");
//Checks if a kernel object with the same name already exists
if( GetLastError() == ERROR_ALREADY_EXISTS )
{
CloseHandle(h);
//error
return ALREADY_RUNNING;
}
//ok
return NONE_RUNNING;
}
this function is used by JustOne.exe.
Now we'll see some ways to patch JustOne.exe in order to support multiple instances.
1. open OllyDbg (
http://www.ollydbg.de/ ) on our JustOne.exe;
2. go in: View -> Executable Modules, select JustOne.exe then right click and select View names;
3. select CreateMutex(W) then right click and select Find reference to import then double click;
Code:
00401040 /$ 83EC 4C SUB ESP,4C
00401043 |. 53 PUSH EBX
00401044 |. 56 PUSH ESI
00401045 |. 68 18214000 PUSH JustOne.00402118 ; /MutexName = "{LuigiLikesCookies}"
0040104A |. 33DB XOR EBX,EBX ; |
0040104C |. 53 PUSH EBX ; |InitialOwner => FALSE
0040104D |. 53 PUSH EBX ; |pSecurity => NULL
0040104E |. FF15 00204000 CALL DWORD PTR DS:[<&KERNEL32.CreateMute>; \CreateMutexW
00401054 |. 8BF0 MOV ESI,EAX
00401056 |. FF15 04204000 CALL DWORD PTR DS:[<&KERNEL32.GetLastErr>; [GetLastError
0040105C |. 3D B7000000 CMP EAX,0B7
00401061 |. 75 0E JNZ SHORT JustOne.00401071
The First Way ( code-patch ):Patch the jump after the GetLastError call, double click on the JNZ instruction and replace JNZ with a JMP:
Code:
00401056 |. FF15 04204000 CALL DWORD PTR DS:[<&KERNEL32.GetLastErr>; [GetLastError
0040105C |. 3D B7000000 CMP EAX,0B7
00401061 EB 0E JMP SHORT JustOne.00401071
The Second Way ( memory-patch ):We patch the name in memory:
Code:
00401045 |. 68 34214000 PUSH JustOne.00402134 ; /MutexName = "{LuigiLikesCookies}"
go at 402118 by using the command line ( ALT + F1 ) write: dump 402118
Code:
00402118 7B 00 4C 00 75 00 69 00 67 00 69 00 4C 00 69 00 {.L.u.i.g.i.L.i.
00402128 6B 00 65 00 73 00 43 00 6F 00 6F 00 6B 00 69 00 k.e.s.C.o.o.k.i.
00402138 65 00 73 00 7D e.s.}
As you can note after each char of:"{LuigiLikesCookies}" there is a null byte in fact CreateMutexW requires strings as Unicode strings. So we have just to replace the old name with a new one.
Note: this approach requires for each new instance to _reassign_ a new name to the kernel object.
Final Note:
To save your patched exe:
1. right click (into CPU window), select Copy to executable -> All modifications
2. right click into the new window, select Save file
Hope may be useful,
- ratsoul