CreateMutexA - ReleaseMutexA

Ask for Help on Using the Language With Memory Hacking Software

Moderators: g3nuin3, SpeedWing, WhiteHat, mezzo

Postby mezzo » Wed Feb 06, 2008 2:45 pm

L. Spiro wrote:The next release allows to call any function in the target process via scripts, regardless of calling type and convention.

This will surely make it easier to write something that can send packets from the target process.

L. Spiro


:shock:
I have my tcpdump and wireshark prepared :-)
this is going to be fun !
- No thanks, I already have a penguin -
User avatar
mezzo
El Mariachi
 
Posts: 739
Joined: Mon Apr 30, 2007 10:27 pm
Location: Antwerp

Postby Shynd » Wed Feb 06, 2008 11:38 pm

Code: Select all
const DWORD ERROR_ALREADY_EXISTS = 0xB7;
MHS_ADDRESS rtlglw32e = 0;
MHS_ADDRESS createmutexa = 0;
MHS_ADDRESS createmutexw = 0;
DWORD dwBPID = 0;

void On_StartUp(HWND mhswin)
{
   //create a new thread instead of doing this in startup
   //opening a debugfile during startup caused MHS to freeze every time,
   //so this is just a hacky way of getting around that, for now
   CloseHandle(CreateThread("WaitForWindow", (DWORD)mhswin));
}

void WaitForWindow(DWORD arg)
{
   //grab the argument passed to the thread
   HWND mhswin = (HWND)arg;
   
   //MHS pops up on top, so wait for it
   while (GetForegroundWindow() != mhswin) Sleep(10);
   Sleep(1000);
   
   //open up whatever game/app (can be almost anything as I made this relatively unspecific)
   DebugFile("C:\\Program Files\\KRU\\Dark Ages\\Darkages.exe", "", true);
   
   //for some reason, rtlglw32e was sometimes equal to zero,
   //so take up to a second to make sure it's not
   for (int i = 0; i < 100; i++)
   {
      rtlglw32e = GetRemoteFuncAddress("ntdll.dll", "RtlGetLastWin32Error");
      Sleep(10);
      if (rtlglw32e > 0) break;
   }
   
   //find both 'CreateMutex'es
   createmutexa = GetRemoteFuncAddress("kernel32.dll", "CreateMutexA");
   createmutexw = GetRemoteFuncAddress("kernel32.dll", "CreateMutexW");
   
   //this seems to have an error in it, somewhere, as it outputs the following:
   //>>RtlGetLastWin32Error: 0x7C910331
   //>>CreateMutexA: 0x00000000
   //>>CreateMutexW: 0x7C80E93F
   //and I know this is wrong because I know that CreateMutexA has a value and is not zero
   //MessageBox(MBS_OK, "Startup", "RtlGetLastWin32Error: 0x%08X\nCreateMutexA: 0x%08X\nCreateMutexW: 0x%08X", rtlglw32e, createmutexa, createmutexw);
   
   //set up our breakpoint
   SCRIPT_ADD_BP bp = {0};
   
   //we set the breakpoint on RtlGetLastWin32Error+9 because the last error has
   //already been passed into EAX at this point
   bp.aAddress = rtlglw32e+9;
   bp.iType = SPBT_EXECUTE;
   bp.iCallback = SYS_FUNCS_SCRIPT_FUNC;
   bp.dwNewParms[1] = 1;
   bp.pcName = "RtlGetLastWin32Error";
   bp.bHardware = true;
   bp.bSet = true;
   
   //add the breakpoint
   AddBreakpoint(&bp, &dwBPID);
   
   //there was a problem with StopStepping() without this sleep here;
   //sometimes it'd stopstepping, sometimes the game would remain paused
   Sleep(250);
   
   //if I used 'if (IsStepping()) StopStepping();' without a 'Sleep(250);',
   //it'd only unpause the game about 1/3rd of the time, and I couldn't
   //figure out why or what was affecting the bug
   StopStepping();
}

void On_BP_1(LPVOID lpvAddress, LPPROC_INFO_MHS lpProcInfo)
{
   //we only want to do stuff if the last error is 0xB7
   if (lpProcInfo->pcContext->Eax == ERROR_ALREADY_EXISTS)
   {
      bool cmFound = false;
      DWORD searchAddress = 0;
      DWORD cmSearch = 0;
      
      //we're going to try to search for a CreateMutex call, so gather
      //the address of where GetLastError was called out of ESP
      ReadProcessMemory(lpProcInfo->hProcess, (void *)lpProcInfo->pcContext->Esp, &searchAddress, 4, NULL);
      
      //let's start searching for the CreateMutex call at searchAddress - 50
      searchAddress -= 50;
      
      for (int i = 0; i < 50; i++)
      {
         //read into cmSearch out of searchAddress
         ReadProcessMemory(lpProcInfo->hProcess, (void *)(searchAddress + i), &cmSearch, 4, NULL);
         //read cmSearch like a pointer, getting the address of CreateMutex out of the IAT
         ReadProcessMemory(lpProcInfo->hProcess, (void *)cmSearch, &cmSearch, 4, NULL);
         
         //if cmSearch is equal to either address, we found it
         if (cmSearch == createmutexa || cmSearch == createmutexw)
         {
            cmFound = true;
            break;
         }
      }
      
      //we go through all the above trouble simply because this is is supposed to be
      //specific to CreateMutex and we want to make sure there was a CreateMutex call
      //before we change the return value of GetLastError
      //GetLastError is called many other times and may have a return value of
      //ERROR_ALREADY_EXISTS because of something else, which we don't want to screw with
      if (cmFound)
      {
         lpProcInfo->pcContext->Eax = 0;
         lpProcInfo->bSetContext = true;
         PrintF("CreateMutex detected!  GetLastError patched.");
      }
   }
}

void On_CloseProcess()
{
   //remove the breakpoint when the opened process is closed
   RemoveBreakpoint(dwBPID);
}


Seems to work, though you may want to remove the breakpoint after CreateMutex has been patched to avoid possible overhead (depending on how often GetLastError is called); can't remove a breakpoint within a breakpoint, so start up another thread to constantly monitor a boolean variable and remove the breakpoint when true.

Another method would be to breakpoint both CreateMutex calls, then breakpoint RtlGetLastWin32Error inside that CreateMutex breakpoint. That's probably a better method and I really wish I had waited until I woke up to try to tackle this problem because I did everything but comment this last night while I was really tired and now it all seems so much easier. Oh well. Either way, you still need to breakpoint RtlGetLastWin32Error+9 and change the value of EAX, so I suppose it wasn't totally in vain.
User avatar
Shynd
Acker
 
Posts: 68
Joined: Fri Jan 05, 2007 2:11 am

Previous

Return to Help

Who is online

Users browsing this forum: No registered users and 0 guests

cron