Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public object ExecuteCommand(short opcode, params object[] args)
- {
- /*
- * SCM Memory Layout:
- * <o> <t> <v>
- *
- * Where:
- * <o> - Opcode(short)
- * <t> - Type(byte)
- * <v> - Value(depends on <t>)
- *
- * While using regular vars is very simple, usage of variables is a bit complicated.
- * Remember that you passing NOT a absolute pointer to your variable, but index in global variable pointer to your variable, i.e
- *
- * Global variable table:
- * <$PLAYER_CHAR> <$PLAYER_ACTOR> <Pointer to your variable> <$SOMETHING_OTHER>
- *
- * While it's simple to use original main.scm global variable table, it's not safe, so i've implemented another "temporary" globals table.
- */
- ScriptCommand cmd = new ScriptCommand(opcode, args);
- uint sz = (uint)(cmd.GetArgumentLength() + ScriptContextSize + sizeof(short));
- int scmData = (int)Native.VirtualAllocEx(GTA.GetInstance().Process.Handle, IntPtr.Zero, sz, AllocationType.Commit, MemoryProtection.ReadWrite);
- int scmHeap = (int)Native.VirtualAllocEx(GTA.GetInstance().Process.Handle, IntPtr.Zero, (uint)cmd.GetVariableLength(), AllocationType.Commit, MemoryProtection.ReadWrite);
- int scmGlobalsTable = (int)Native.VirtualAllocEx(GTA.GetInstance().Process.Handle, IntPtr.Zero, (uint)(cmd.GetVariableCount() * 4), AllocationType.Commit, MemoryProtection.ReadWrite);
- int argPtr = scmData + ScriptContextSize + 2;
- int vCount = 0;
- int heapPtr = scmHeap;
- int globalPtr = scmHeap;
- if (scmData == 0 || scmHeap == 0)
- throw new ArgumentException(string.Format("Failed to allocate {0} bytes for SCM context", sz));
- Console.WriteLine("Allocated {0} bytes", sz);
- GTA.GetInstance().WriteMemory(scmData + 0x10, (argPtr - 2) - OffsetSCMBase);
- GTA.GetInstance().WriteMemory(argPtr - 2, (short)opcode);
- foreach (object arg in cmd.Arguments)
- {
- if (arg is byte)
- {
- GTA.GetInstance().WriteMemory(argPtr, (byte)0x04);
- GTA.GetInstance().WriteMemory(argPtr + 1, arg);
- argPtr += 2;
- continue;
- }
- if (arg is short)
- {
- GTA.GetInstance().WriteMemory(argPtr, (byte)0x05);
- GTA.GetInstance().WriteMemory(argPtr + 1, arg);
- argPtr += 3;
- continue;
- }
- if (arg is int)
- {
- GTA.GetInstance().WriteMemory(argPtr, (byte)0x01);
- GTA.GetInstance().WriteMemory(argPtr + 1, arg);
- argPtr += 5;
- continue;
- }
- if (arg is float)
- {
- GTA.GetInstance().WriteMemory(argPtr, (byte)0x06);
- GTA.GetInstance().WriteMemory(argPtr + 1, arg);
- argPtr += 5;
- continue;
- }
- if (arg is ScriptResult)
- {
- GTA.GetInstance().WriteMemory(argPtr, (byte)0x02);
- GTA.GetInstance().WriteMemory(argPtr + 1, (int)((scmGlobalsTable - OffsetSCMBase) + (vCount * 4))); // Pointer to our variable in globals table
- GTA.GetInstance().WriteMemory(globalPtr, heapPtr);
- heapPtr += Marshal.SizeOf((arg as ScriptResult).ResultType);
- vCount++;
- argPtr += 5;
- continue;
- }
- throw new ArgumentException(string.Format("Incorrect type specified \"{0}\" in ExecuteCommand(only byte, short, int and float is supported)", arg.GetType().FullName));
- }
- heapPtr = scmHeap;
- //vPtr = scmHeap - OffsetSCMBase;
- new Shellcode().
- Append("mov ecx, " + scmData).
- Append("mov edx, " + OffsetExecuteCommand).
- Append("call edx").
- Assemble().
- Execute();
- // Collect result
- foreach (object arg in cmd.Arguments)
- {
- if (arg is ScriptResult)
- {
- ScriptResult res = (arg as ScriptResult);
- res.Data = GTA.GetInstance().ReadMemory(heapPtr, res.ResultType);
- heapPtr += Marshal.SizeOf(res.ResultType);
- }
- }
- return null;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement