/* Universal V1 name patch! */ private bool PatchV1Names(PEHeader hdr) { byte[] data; int bytesRead; UInt32 loc; /* Find the instruction we want to patch. */ foreach (IMAGE_SECTION_HEADER sec in hdr.Sections) { if (sec.name.Equals(".text")) { if (!ReadProcessMemory(0x00400000 + sec.virtAddr, sec.virtSz, out data, out bytesRead)) { return(false); } loc = FindNextPtr(sec, data, 0xFFFFAE35, 0); while (loc != UInt32.MaxValue) { /* See if this is one of the two mov dword ptr [edi+18h], 0FFFFAE35h * occurances, and if it is, is it the correct one... */ if (data[loc - 1] == 0x18 && data[loc - 2] == 0x47 && data[loc - 3] == 0xC7 && data[loc + 4] == 0xE8) { /* Patch the value in correctly. */ data[loc] = 0xFF; data[loc + 1] = 0xFF; if (!WriteProcessMemory(0x00400000 + sec.virtAddr, sec.virtSz, data, out bytesRead)) { return(false); } return(true); } loc = FindNextPtr(sec, data, 0xFFFFAE35, loc); } } } Console.Out.WriteLine("Couldn't find location to patch for v1 name color."); return(false); }
/* Universal Cusshack! */ private bool PatchCusshack(PEHeader hdr) { byte[] data; int bytesRead; string censorStr = "#!@%#!@%#!@%#!@%#!@%#!@%#!@%#!@%#!@%"; UInt32 censorStrLoc = UInt32.MaxValue, ptrLoc; /* First, find the location of the censoring string. It should * always be in the .data segment of the binary. */ foreach (IMAGE_SECTION_HEADER sec in hdr.Sections) { if (sec.name.Equals(".data")) { if (!ReadProcessMemory(0x00400000 + sec.virtAddr, sec.virtSz, out data, out bytesRead)) { return(false); } censorStrLoc = FindString(sec, data, Encoding.ASCII.GetBytes(censorStr)); if (censorStrLoc == UInt32.MaxValue) { return(false); } } } if (censorStrLoc == UInt32.MaxValue) { return(false); } /* Next, find the one and only absolute reference to it in the * .text segment. */ foreach (IMAGE_SECTION_HEADER sec in hdr.Sections) { if (sec.name.Equals(".text")) { if (!ReadProcessMemory(0x00400000 + sec.virtAddr, sec.virtSz, out data, out bytesRead)) { return(false); } ptrLoc = FindPtr(sec, data, censorStrLoc); if (ptrLoc == UInt32.MaxValue) { return(false); } ptrLoc -= 0x00400000 + sec.virtAddr; /* See if the value 46 bytes up is a jz instruction, as we expect. */ if (data[ptrLoc - 46] == 0x74) { /* Patch the instruction to two nops instead. */ data[ptrLoc - 46] = 0x90; data[ptrLoc - 45] = 0x90; if (!WriteProcessMemory(0x00400000 + sec.virtAddr, sec.virtSz, data, out bytesRead)) { return(false); } return(true); } else if (data[ptrLoc - 46] == 0x90 && data[ptrLoc - 45] == 0x90) { Console.Out.WriteLine("Cusshack appears to have been applied manually!"); return(true); } else { Console.Out.WriteLine("Invalid data where jz was expected."); return(false); } } } return(false); }
public bool PatchPSO(bool v1, bool cuss, bool music, bool mapfix, string serverName = "sylverant.net") //Adding serverName variable to allow connecting a different server { PEHeader hdr = new PEHeader(this); long start = DateTime.Now.Ticks; bool done = false; byte[] data; int bytesRead; while ((start + 100000 > DateTime.Now.Ticks) && !done) { foreach (IMAGE_SECTION_HEADER sec in hdr.Sections) { if (!ReadProcessMemory(0x00400000 + sec.virtAddr, sec.virtSz, out data, out bytesRead)) { return(false); } if (serverName != null) { if (!serverName.Trim().Equals(string.Empty)) { PatchGServer(sec, data, serverName); } else { PatchGServer(sec, data); } } if (music) { MusicPatch(sec, data); } if (mapfix && sec.name.Equals(".data")) { if (!DetectMapfix(sec, data)) { PerformMapfix(sec, data); } else { Console.Out.WriteLine("Mapfix appears to have been done manually!"); } } } if (v1) { PatchV1Names(hdr); } if (cuss) { PatchCusshack(hdr); } } return(done); }