public void Patch(LeagueProcess league) { uint createFileARefPointer = this.CreateFileARefOffset + league.Base; uint createFileAPointer = this.CreateFileAOffset + league.Base; uint returnAddress = this.ReturnAddressOffset + league.Base; uint freePointer = this.FreePointerOffset + league.Base; uint freeFunction = this.FreeFunctionOffset + league.Base; // wait untill CreateFileA has been used and unpacmaned league.WaitPointerEquals(createFileARefPointer, createFileAPointer); // wait until free pointer has been set league.WaitPointerNonZero(freePointer); // read trampoline shellcode that league creates for CreateFileA uint createFileATrampolinePointer = league.Read <uint>(createFileAPointer); ImportTrampoline originalCreateFileATrampoline = league.Read <ImportTrampoline>(createFileATrampolinePointer); uint payloadPointer = league.AllocateMemory(0x1000); Payload payload = new Payload( payloadPointer: payloadPointer, originalCreateFileATrampoline: originalCreateFileATrampoline, prefix: PrefixNormalized, originalFreePointer: freeFunction, findReturnAddress: returnAddress ); uint hookCreateFileAPointer = payload.HookCreateFileAPointer(payloadPointer); uint hookFreePointer = payload.HookFreePointer(payloadPointer); ImportTrampoline hookCreateFileATrampoline = new ImportTrampoline(hookCreateFileAPointer); league.Write(payloadPointer, payload); league.MarkMemoryExecutable(payloadPointer, 0x1000); // write hooks league.Write(freePointer, hookFreePointer); league.Write(createFileATrampolinePointer, hookCreateFileATrampoline); }
public void Patch(LeagueProcess league) { uint codePointer = league.AllocateMemory(0x900); uint codeVerifyPointer = codePointer + 0x000; uint codePrefixFnPointer = codePointer + 0x100; uint codeOpenPointer = codePointer + 0x200; uint codeCheckAccessPointer = codePointer + 0x300; uint codeCreateIteratorPointer = codePointer + 0x400; uint codeVectorDeleterPointer = codePointer + 0x500; uint codeIsRadsPointer = codePointer + 0x600; league.WriteMemory(codeVerifyPointer, new byte[] { 0xB8, 0x01, 0x00, 0x00, 0x00, 0xC3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, }); league.WriteMemory(codePrefixFnPointer, new byte[] { 0x57, 0x56, 0x8b, 0x54, 0x24, 0x0c, 0x8b, 0x74, 0x24, 0x14, 0x89, 0xd7, 0xac, 0xaa, 0x84, 0xc0, 0x75, 0xfa, 0x8b, 0x74, 0x24, 0x10, 0x83, 0xef, 0x01, 0xac, 0xaa, 0x84, 0xc0, 0x75, 0xfa, 0x5e, 0x89, 0xd0, 0x5f, 0xc3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, }); league.WriteMemory(codeOpenPointer, new byte[] { 0x56, 0x53, 0x81, 0xec, 0x14, 0x02, 0x00, 0x00, 0x8b, 0x41, 0x04, 0x8b, 0x58, 0x08, 0x8b, 0x03, 0x8b, 0x30, 0x8d, 0x41, 0x0c, 0x89, 0x44, 0x24, 0x08, 0x8b, 0x84, 0x24, 0x20, 0x02, 0x00, 0x00, 0x89, 0x44, 0x24, 0x04, 0x8d, 0x44, 0x24, 0x10, 0x89, 0x04, 0x24, 0xff, 0x51, 0x08, 0x8b, 0x94, 0x24, 0x24, 0x02, 0x00, 0x00, 0x89, 0xd9, 0x89, 0x04, 0x24, 0x89, 0x54, 0x24, 0x04, 0xff, 0xd6, 0x83, 0xec, 0x08, 0x81, 0xc4, 0x14, 0x02, 0x00, 0x00, 0x5b, 0x5e, 0xc2, 0x08, 0x00, 0x90, 0x90, }); league.WriteMemory(codeCheckAccessPointer, new byte[] { 0x56, 0x53, 0x81, 0xec, 0x14, 0x02, 0x00, 0x00, 0x8b, 0x41, 0x04, 0x8b, 0x58, 0x08, 0x8b, 0x03, 0x8b, 0x70, 0x04, 0x8d, 0x41, 0x0c, 0x89, 0x44, 0x24, 0x08, 0x8b, 0x84, 0x24, 0x20, 0x02, 0x00, 0x00, 0x89, 0x44, 0x24, 0x04, 0x8d, 0x44, 0x24, 0x10, 0x89, 0x04, 0x24, 0xff, 0x51, 0x08, 0x8b, 0x94, 0x24, 0x24, 0x02, 0x00, 0x00, 0x89, 0xd9, 0x89, 0x04, 0x24, 0x89, 0x54, 0x24, 0x04, 0xff, 0xd6, 0x83, 0xec, 0x08, 0x81, 0xc4, 0x14, 0x02, 0x00, 0x00, 0x5b, 0x5e, 0xc2, 0x08, 0x00, 0x90, }); league.WriteMemory(codeCreateIteratorPointer, new byte[] { 0x31, 0xc0, 0xc2, 0x08, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, }); league.WriteMemory(codeVectorDeleterPointer, new byte[] { 0x89, 0xc8, 0xc2, 0x04, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, }); league.WriteMemory(codeIsRadsPointer, new byte[] { 0x31, 0xc0, 0xc3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, }); // Mark shellcode executable // League AC will trip over if we allocate ReadWriteExecutable in one go // So page can only be either ReadWrite or Executable league.MarkMemoryExecutable(codePointer, 0x900); uint modifiedPMethPointer = league.Allocate <EVP_PKEY_METHOD>(); uint orgignalPMethArrayPointer = this.PMethArrayOffset + league.Base; // Read first pointer when it gets initialized(tnx pacman) uint originalPMethFirstPointer = league.WaitPointerNonZero(orgignalPMethArrayPointer); // Read first PKEY_METHOD EVP_PKEY_METHOD originalPMeth = league.Read <EVP_PKEY_METHOD>(originalPMethFirstPointer); // Change verify function pointer originalPMeth.verify = codeVerifyPointer; // Write our new PKEY_METHOD league.Write(modifiedPMethPointer, originalPMeth); // Write the pointer to out PKEY_METHOD into pointer array league.Write(orgignalPMethArrayPointer, modifiedPMethPointer); uint orginalFileProviderListPointer = this.FileProviderListOffset + league.Base; // Those get deallocated upon exit so we need separate pages uint modifiedFileProviderPointer = league.Allocate <FileProvider>(); uint modifiedFileProviderVtablePointer = league.Allocate <FileProviderVtable>(); league.Write(modifiedFileProviderPointer, new FileProvider { vtable = modifiedFileProviderVtablePointer, list = orginalFileProviderListPointer, prefixFn = codePrefixFnPointer, prefix = _prefixBytes, }); league.Write(modifiedFileProviderVtablePointer, new FileProviderVtable { Open = codeOpenPointer, CheckAccess = codeCheckAccessPointer, CreateIterator = codeCreateIteratorPointer, VectorDeleter = codeVectorDeleterPointer, IsRads = codeIsRadsPointer, }); // Wait until providers have been registerd(first pointer turns non-0) league.WaitPointerNonZero(orginalFileProviderListPointer); FileProviderList originalFileProviderList = league.Read <FileProviderList>(orginalFileProviderListPointer); league.Write(orginalFileProviderListPointer, new FileProviderList { fileProviderPointer0 = modifiedFileProviderPointer, fileProviderPointer1 = originalFileProviderList.fileProviderPointer0, fileProviderPointer2 = originalFileProviderList.fileProviderPointer1, fileProviderPointer3 = originalFileProviderList.fileProviderPointer2, size = originalFileProviderList.size + 1, }); }