Cpu general purpose register context. Only the registers you change will be set before the call.
Beispiel #1
0
        //CallAddressEx usage
        //public void Function(Arg1, Arg2, Arg3);
        //CallAddressEx(FunctionAddress, null, false, Arg1, Arg2, Arg3);
        //assembly:
        //push  Arg3
        //push  Arg2
        //push  Arg1
        //call  Function
        /// <summary>
        /// Extended function call with optional context, arguments, and return value.  Average execution time of 1.3ms without return or 1.75ms with return.
        /// </summary>
        /// <param name="address">Xbox procedure address.</param>
        /// <param name="context">Cpu context.  This parameter may be null.</param>
        /// <param name="pushArgs">Arguments to be pushed before the call is made.  These are optional of course.</param>
        /// <returns></returns>
        public uint CallAddressEx(uint address, CPUContext context, bool returnValue, params object[] pushArgs)
        {
            #region Build Call Script

            // buffer to hold our call data
            System.IO.MemoryStream callScript = new System.IO.MemoryStream();
            BinaryWriter call = new BinaryWriter(callScript);
            call.BaseStream.Position = 0;

            // push arguments in reverse order
            for (int i = pushArgs.Length - 1; i >= 0; i--)
            {
                call.Write((byte)0x68); //push
                call.Write(Convert.ToUInt32(pushArgs[i]));
            }

            if (context != null)
            {
                // assign registers
                if (context.Eax != null)
                {
                    call.Write((byte)0xB8); //mov eax
                    call.Write(Convert.ToUInt32(context.Eax));
                }
                if (context.Ebx != null)
                {
                    call.Write((byte)0xBB); //mov ebx
                    call.Write(Convert.ToUInt32(context.Ebx));
                }
                if (context.Ecx != null)
                {
                    call.Write((byte)0xB9); //mov ecx
                    call.Write(Convert.ToUInt32(context.Ecx));
                }
                if (context.Edx != null)
                {
                    call.Write((byte)0xBA); //mov edx
                    call.Write(Convert.ToUInt32(context.Edx));
                }
                if (context.Esi != null)
                {
                    call.Write((byte)0xBE); //mov esi
                    call.Write(Convert.ToUInt32(context.Esi));
                }
                if (context.Edi != null)
                {
                    call.Write((byte)0xBF); //mov edi
                    call.Write(Convert.ToUInt32(context.Edi));
                }
                if (context.Esp != null)
                {
                    call.Write((byte)0xBC); //mov esp
                    call.Write(Convert.ToUInt32(context.Esp));
                }
                if (context.Ebp != null)
                {
                    call.Write((byte)0xBD); //mov ebp
                    call.Write(Convert.ToUInt32(context.Ebp));
                }

                // assign xmm registers
                // remember that its a pointer, not a value you are db'ing
                // so we need to dump the values somewhere, then store the pointers to those...

                uint XmmContextBuffer = 0x10004;
                if (context.Xmm0 != null)
                {
                    SetMemory(XmmContextBuffer, Convert.ToSingle(context.Xmm0));
                    call.Write(0x05100FF3); //movss xmm0
                    call.Write(XmmContextBuffer);   //dword ptr ds:[addr]
                }
                if (context.Xmm1 != null)
                {
                    SetMemory(XmmContextBuffer + 4, Convert.ToSingle(context.Xmm1));
                    call.Write(0x0D100FF3); //movss xmm1
                    call.Write(XmmContextBuffer + 4);
                }
                if (context.Xmm2 != null)
                {
                    SetMemory(XmmContextBuffer + 8, Convert.ToSingle(context.Xmm2));
                    call.Write(0x15100FF3); //movss xmm2
                    call.Write(XmmContextBuffer + 8);
                }
                if (context.Xmm3 != null)
                {
                    SetMemory(XmmContextBuffer + 12, Convert.ToSingle(context.Xmm3));
                    call.Write(0x1D100FF3); //movss xmm3
                    call.Write(XmmContextBuffer + 12);
                }
                if (context.Xmm4 != null)
                {
                    SetMemory(XmmContextBuffer + 16, Convert.ToSingle(context.Xmm4));
                    call.Write(0x25100FF3); //movss xmm4
                    call.Write(XmmContextBuffer + 16);
                }
                if (context.Xmm5 != null)
                {
                    SetMemory(XmmContextBuffer + 20, Convert.ToSingle(context.Xmm5));
                    call.Write(0x2D100FF3); //movss xmm5
                    call.Write(XmmContextBuffer + 20);
                }
                if (context.Xmm6 != null)
                {
                    SetMemory(XmmContextBuffer + 24, Convert.ToSingle(context.Xmm6));
                    call.Write(0x35100FF3); //movss xmm6
                    call.Write(XmmContextBuffer + 24);
                }
                if (context.Xmm7 != null)
                {
                    SetMemory(XmmContextBuffer + 28, Convert.ToSingle(context.Xmm7));
                    call.Write(0x3D100FF3); //movss xmm7
                    call.Write(XmmContextBuffer + 28);
                }
            }

            // call address and store result
            //call	dword ptr ds:[CallAddress]
            //mov	dword ptr ds:[ReturnAddress], eax
            //mov   eax, 02DB0000h  ;fake success
            //retn  10h
            call.Write((ushort)0x15FF);
            call.Write((uint)(ScriptBufferAddress + call.BaseStream.Position + 17));
            call.Write((byte)0xA3);
            call.Write((uint)0x10000);
            call.Write(0x00DB02B8);
            call.Write(0x0010C200);
            call.Write(address);
            #endregion

            // inject call script
            if (callScript.Length > ScriptBufferSize) throw new Exception("Script too big. Try allocating more memory and specifying new script buffer information.");
            SetMemory(ScriptBufferAddress, callScript.ToArray());
            call.Close();

            // execute script via hijacked crashdump function
            FlushSocketBuffer();
            SendCommand("crashdump");

            // return the value of eax after the call
            if (returnValue) return GetUInt32(0x10000);
            else return 0;
        }
Beispiel #2
0
        //CallAddressEx usage
        //public void Function(Arg1, Arg2, Arg3);
        //CallAddressEx(FunctionAddress, null, false, Arg1, Arg2, Arg3);
        //assembly:
        //push  Arg3
        //push  Arg2
        //push  Arg1
        //call  Function
		/// <summary>
		/// Extended function call with optional context, arguments, and return value.  Average execution time of 1.3ms without return or 1.75ms with return.
        /// </summary>
		/// <param name="address">Xbox procedure address.</param>
		/// <param name="context">Cpu context.  This parameter may be null.</param>
		/// <param name="pushArgs">Arguments to be pushed before the call is made.  These are optional of course.</param>
		/// <returns></returns>
		public uint CallAddressEx(uint address, CPUContext context, bool returnValue, params object[] pushArgs)
		{
			// NOTE: Documented execution timing is probably different now that we don't use straight up objects in the CPUContext
			// buffer to hold our call data
            using (System.IO.MemoryStream callScript = new System.IO.MemoryStream())
            using (BinaryWriter call = new BinaryWriter(callScript))
            {
                call.Write(LowLevel.Intel.x86.pushad);

                // push arguments in reverse order
                for (int i = pushArgs.Length - 1; i >= 0; i--)
                {
                    call.Write(LowLevel.Intel.x86.push_prefix_dword);
                    call.Write(Util.ObjectToDwordBytes(pushArgs[i]));    // hack: improper conversion of floating point values
                }

                if (context != null)
                {
                    // assign registers
                    if (context.Eax.HasValue)
                    {
                        call.Write(LowLevel.Intel.x86.mov_eax_prefix_dword);
                        call.Write(context.Eax.Value);
                    }
					if (context.Ebx.HasValue)
                    {
						call.Write(LowLevel.Intel.x86.mov_ebx_prefix_dword);
						call.Write(context.Ebx.Value);
                    }
					if (context.Ecx.HasValue)
                    {
						call.Write(LowLevel.Intel.x86.mov_ecx_prefix_dword);
						call.Write(context.Ecx.Value);
                    }
					if (context.Edx.HasValue)
                    {
						call.Write(LowLevel.Intel.x86.mov_edx_prefix_dword);
						call.Write(context.Edx.Value);
                    }
					if (context.Esi.HasValue)
                    {
						call.Write(LowLevel.Intel.x86.mov_esi_prefix_dword);
						call.Write(context.Esi.Value);
                    }
					if (context.Edi.HasValue)
                    {
						call.Write(LowLevel.Intel.x86.mov_edi_prefix_dword);
						call.Write(context.Edi.Value);
                    }
					if (context.Esp.HasValue)
                    {
						call.Write(LowLevel.Intel.x86.mov_esp_prefix_dword);
						call.Write(context.Esp.Value);
                    }
					if (context.Ebp.HasValue)
                    {
						call.Write(LowLevel.Intel.x86.mov_ebp_prefix_dword);
						call.Write(context.Ebp.Value);
                    }

                    // assign xmm registers
                    // remember that its a pointer, not a value you are db'ing
                    // so we need to dump the values somewhere, then store the pointers to those...

					if (context.Xmm0.HasValue)
                    {
                        SetMemory(kAddressOfXmmContextBuffer, (float)context.Xmm0.Value);    // shouldnt assume its floating point input but meh
                        call.Write(LowLevel.Intel.SSE.movss_xmm0_prefix_addr);
                        call.Write(kAddressOfXmmContextBuffer);   //dword ptr ds:[addr]
                    }
					if (context.Xmm1.HasValue)
                    {
						SetMemory(kAddressOfXmmContextBuffer + 4, (float)context.Xmm0.Value);
						call.Write(LowLevel.Intel.SSE.movss_xmm1_prefix_addr);
                        call.Write(kAddressOfXmmContextBuffer + 4);
                    }
					if (context.Xmm2.HasValue)
                    {
						SetMemory(kAddressOfXmmContextBuffer + 8, (float)context.Xmm0.Value);
						call.Write(LowLevel.Intel.SSE.movss_xmm2_prefix_addr);
                        call.Write(kAddressOfXmmContextBuffer + 8);
                    }
					if (context.Xmm3.HasValue)
                    {
						SetMemory(kAddressOfXmmContextBuffer + 12, (float)context.Xmm0.Value);
						call.Write(LowLevel.Intel.SSE.movss_xmm3_prefix_addr);
                        call.Write(kAddressOfXmmContextBuffer + 12);
                    }
					if (context.Xmm4.HasValue)
                    {
						SetMemory(kAddressOfXmmContextBuffer + 16, (float)context.Xmm0.Value);
						call.Write(LowLevel.Intel.SSE.movss_xmm4_prefix_addr);
                        call.Write(kAddressOfXmmContextBuffer + 16);
                    }
					if (context.Xmm5.HasValue)
                    {
						SetMemory(kAddressOfXmmContextBuffer + 20, (float)context.Xmm0.Value);
						call.Write(LowLevel.Intel.SSE.movss_xmm5_prefix_addr);
                        call.Write(kAddressOfXmmContextBuffer + 20);
                    }
					if (context.Xmm6.HasValue)
                    {
						SetMemory(kAddressOfXmmContextBuffer + 24, (float)context.Xmm0.Value);
						call.Write(LowLevel.Intel.SSE.movss_xmm6_prefix_addr);
                        call.Write(kAddressOfXmmContextBuffer + 24);
                    }
					if (context.Xmm7.HasValue)
                    {
						SetMemory(kAddressOfXmmContextBuffer + 28, (float)context.Xmm0.Value);
						call.Write(LowLevel.Intel.SSE.movss_xmm7_prefix_addr);
                        call.Write(kAddressOfXmmContextBuffer + 28);
                    }
                }

                // call address and store result
                //pushad
                //push  Arg3
                //push  Arg2
                //push  Arg1
                //call	dword ptr ds:[CallAddress]
                //mov	dword ptr ds:[ReturnAddress], eax
                //popad
                //mov   eax, 02DB0000h  ;fake success
                //retn  10h
                call.Write(LowLevel.Intel.x86.call_prefix_absolute);
                call.Write((uint)(XboxHistory.ScriptBufferAddress + call.BaseStream.Position + 18));
                call.Write((byte)0xA3);
                call.Write(kAddressOfReturnValue);
                call.Write(LowLevel.Intel.x86.popad);
                call.Write(0xDB0000B8);
                call.Write(0x0010C202);
                call.Write(address);

                // inject call script
                if (callScript.Length > XboxHistory.ScriptBufferSize) throw new Exception("Script too big. Try allocating more memory and specifying new script buffer information.");
                SetMemory(XboxHistory.ScriptBufferAddress, callScript.ToArray());
            }

            // execute script via hijacked crashdump function
            SendCommand("crashdump");

			// return the value of eax after the call
			if (returnValue) return GetUInt32(kAddressOfReturnValue);
            else return 0;
		}