예제 #1
0
        private void _buildAsmArrays()
        {
            if (OriginalLocalCode == null)
            {
                OriginalLocalCode = RBytes(OriginalLocalCodeStartOffset.ToInt64(), OriginalLocalCodeLength);
            }

            using (var _customRemoteCodeMemoryStream = new MemoryStream(OriginalLocalCodeLength))
            {
                //Start building wrapped user code at the location immediately after the copy of the original
                //code ends (unless OriginalCodeAtEnd is defined, in which case, it's at the beginning of CustomRemoteCodeHandle) :
                var customRemoteCodeCodeBuilder = new X86Writer(_customRemoteCodeMemoryStream, (IntPtr)(CustomRemoteCodeHandle.GetHandle().ToInt64()));

                //If OriginalCodeAtEnd is not defined, write the original code at the start of the custom remote code:
                if (!OriginalCodeAtEnd)
                {
                    _customRemoteCodeMemoryStream.Write(OriginalLocalCode, 0, OriginalLocalCodeLength);
                }

                BuildCustomRemoteCode(customRemoteCodeCodeBuilder, _customRemoteCodeMemoryStream);

                //If OriginalCodeAtEnd is defined, write the original code at the end of the custom remote code:
                if (OriginalCodeAtEnd)
                {
                    _customRemoteCodeMemoryStream.Write(OriginalLocalCode, 0, OriginalLocalCodeLength);
                }

                //Jump to return offset at end of wrapped function:
                customRemoteCodeCodeBuilder.Jmp(CustomRemoteCodeReturnDestinationOffset);

                //Copy the bytes of the ASM to our array before exiting the "using" statement and disposing the MemoryStream:
                CustomRemoteCode = _customRemoteCodeMemoryStream.ToArray();
            }

            using (var _customLocalCodeMemoryStream = new MemoryStream(OriginalLocalCodeLength))
            {
                var customLocalCodeCodeBuilder = new X86Writer(_customLocalCodeMemoryStream, OriginalLocalCodeStartOffset);

                // Jump to our wrapped code instead of doing the original code:
                customLocalCodeCodeBuilder.Jmp(CustomRemoteCodeHandle.GetHandle());

                // Fill in the rest of the original instructions with NOP's:
                while (_customLocalCodeMemoryStream.Position < OriginalLocalCodeLength)
                {
                    customLocalCodeCodeBuilder.Nop();
                }

                CustomLocalCode = _customLocalCodeMemoryStream.ToArray();
            }
        }
예제 #2
0
        public void PatchCode(bool force = false)
        {
            if (IsPatched && !force)
            {
                return;
            }

            //Write the wrapped code to the allocated memory region:
            var wrappedCodeHandle = CustomRemoteCodeHandle.GetHandle();

            WBytes((wrappedCodeHandle, wrappedCodeHandle), CustomRemoteCode);

            //Flush instruction cache for wrapped code:
            Kernel.FlushInstructionCache(DARKSOULS.GetHandle(), CustomRemoteCodeHandle.GetHandle(), (UIntPtr)CustomLocalCodeAllocSize);

            /*
             *
             * >> The rest of this method: <<
             *
             * Patch original local code while Dark Souls is suspended so that there will be a 0.0% chance of the
             * game trying to execute only-partially-overridden code instead of the usual 0.00000001% chance ;)
             *
             */

            //Suspend execution of Dark Souls process:
            DARKSOULS.Suspend();

            //Overwrite the original local code with the custom local code:
            WBytes((OriginalLocalCodeStartOffset, OriginalLocalCodeStartOffset), CustomLocalCode);

            //Flush the instruction cache over the span of the local code:
            Kernel.FlushInstructionCache(DARKSOULS.GetHandle(), OriginalLocalCodeStartOffset, (UIntPtr)OriginalLocalCodeLength);

            //Resume execution of Dark Souls process:
            DARKSOULS.Resume();

            IsPatched = true;
        }