samuri25404 Grandmaster Cheater
Reputation: 7
Joined: 04 May 2007 Posts: 955 Location: Why do you care?
|
Posted: Sun Jan 06, 2008 2:38 pm Post subject: |
|
|
If what you want to do is write an auto assembly script into a program, go here:
My Opcode.DLL post
Then here's a class I wrote a little while ago:
Code: |
using System;
using System.Collections.Generic;
using Opcode;
namespace YOURNAMESPACE
{
internal static class AAParser
{
private static List<Label> Alloced; //We're just using a label because it's easy
private static List<Label> Labeled;
public static List<Label> Symbols; //symbols from registersymbol
public static bool DoAA(string[] Script, out int Spot)
{
Alloced = new List<Label>();
Labeled = new List<Label>();
Symbols = new List<Label>(); //init them so things from the previous call don't mess up the current call
string[] script = new string[Script.Length];
for (int i = 0; i < Script.Length; i++)
{
script[i] = Script[i].ToUpper();
}
if (!Build(Script, out Spot))
return false;
Spot = -1; //because we do Spot++ at the beginning of the loop
string CurrentAddress = String.Empty;
foreach (string s in script)
{
Spot++;
if (s.StartsWith("//")) continue;
if (CurrentAddress == "")
{
//either we're in the header, there's an upcoming address
if (IsLabeled(s))
{
//set the current address
CurrentAddress = SetCurrentAddress(s);
continue;
}
}
else
{
//we need to do what it tells us :
//possible things:
// set current address
// asm
// get the header
if (IsLabeled(s))
{ //set the current address
CurrentAddress = SetCurrentAddress(s);
}
if (IsHeader(s))
continue;
if (s == "[DISABLE]")
continue;
else //asm
{
int Size;
if (!DoInstruction(CurrentAddress, s, out Size))
return false;
//calculate the new address
uint Address = uint.Parse(CurrentAddress);
Address += (uint)Size;
CurrentAddress = Address.ToString(); //address will be in base-10 (decimal)
continue;
}
}
}
return true;
}
private static bool Build(string[] Script, out int Spot) //make sure that it's ok
{ //In here we go ahead and label everything for the main method
Spot = -1; //because we do Spot++ at the beginning of the loop
foreach (string s in Script)
{
Spot++;
if (s == "[ENABLE]" || s == "[DISABLE]") continue;
if (s.StartsWith("//")) continue;
if (s.StartsWith("ALLOC")) //it'll be in all caps from the calling method
{
DoAlloc(s);
}
if (s.StartsWith("LABEL"))
{
DoLabel(s);
}
if (s.StartsWith("REGISTERSYMBOL"))
{
if (!DoRegis(s)) return false;
}
///////// out of header //////////
//now we can either have a label/address or assembly
//we'll just check out the label/address to see if it's valid,
//then go to the next str
if (s.EndsWith(":")) //it's a label/address to write to
{
string trimmed = s.Remove(s.Length - 1); //-1 because arrays are 0 based
if (IsNumeric(trimmed)) continue;
if (IsLabeled(trimmed))
{ //check if it's allocated, in which it can have asm following it, otherwise it needs to have either
//a label following it, or a [DISABLE]
Label l = Array.Find<Label>(Alloced.ToArray(), mypred);
if (l.Address != String.Empty) //it is allocated, we can continue
continue;
else
{ //check if there's another label following it, otherwise there's an error
for (int i = Spot; i < Script.Length; i++)
{
if (Script[i] == "") continue;
if (Script[i] == "[DISABLE]") break;
if (IsAddress(Script[i]) || IsLabeled(Script[i])) break;
return false; //nothing good came up
}
}
continue;
}
return false; //we'd have continued if a valid condition had been met
}
}
return true;
}
private static int[] UpdatePos(string s, bool Comma)
{
// ( = 0
// if comma : , = 1 ; else ) = 1
// if comma : ) = 2
int[] ints = new int[2];
if (Comma) ints = new int[3];
ints[0] = s.IndexOf('(');
if (Comma)
{
ints[1] = s.IndexOf(',');
ints[2] = s.IndexOf(')');
}
else
{
ints[1] = s.IndexOf(')');
}
return ints;
}
private static void DoAlloc(string s)
{
char[] Tokens = new char[s.Length];
Tokens = s.ToCharArray();
//a l l o c _ ( VARNAME , SIZE )
//note that _ is used to represent spaces
int[] ints = new int[3];
ints[0] = Array.IndexOf(Tokens, "(");
ints[1] = Array.IndexOf(Tokens, ",");
ints[2] = Array.IndexOf(Tokens, ")");
//formalize
string zenew = s;
if (Tokens[ints[0] - 1] != ' ') { zenew.Insert(ints[0] - 1, " "); ints = UpdatePos(zenew, true); }
if (Tokens[ints[0] + 1] == ' ') { zenew.Remove(ints[0] + 1, 1); ints = UpdatePos(zenew, true); }
if (Tokens[ints[1] - 1] == ' ') { zenew.Remove(ints[1] - 1, 1); ints = UpdatePos(zenew, true); }
if (Tokens[ints[1] + 1] == ' ') { zenew.Remove(ints[1] + 1, 1); ints = UpdatePos(zenew, true); }
if (Tokens[ints[2] - 1] == ' ') { zenew.Remove(ints[2] - 1, 1); ints = UpdatePos(zenew, true); }
//update the array and make positions easier
Tokens = zenew.ToCharArray();
int OpenP = Array.IndexOf(Tokens, "(");
int comma = Array.IndexOf(Tokens, ",");
int CloseP = Array.IndexOf(Tokens, ")");
//prepare the allocation
string Allocname = String.Empty;
string Allocsize = String.Empty;
for (int i = OpenP + 1; i < comma; i++)
{
Allocname += Tokens[i];
}
for (int i = comma + 1; i < CloseP; i++)
{
Allocsize += Tokens[i];
}
ulong Size = ulong.Parse(Allocsize);
//allocate
IntPtr Address = Main.preader.Allocate((IntPtr)null, Size); //Pass in null to have Windows generate something
//and it returns the address
//add the allocated thing to the List<Label>
Label l = new Label();
l.mnemonic = Allocname;
l.Address = Address.ToString();
Alloced.Add(l);
}
private static void DoLabel(string s)
{
char[] Tokens = new char[s.Length];
Tokens = s.ToCharArray();
// L A B E L _ ( VARNAME )
int[] ints = new int[2];
ints[0] = Array.IndexOf(Tokens, "(");
ints[1] = Array.IndexOf(Tokens, ")");
//formalize
string zenew = s;
if (Tokens[ints[0] - 1] != ' ') { zenew.Insert(ints[0] - 1, " "); ints = UpdatePos(zenew, false); }
if (Tokens[ints[0] + 1] == ' ') { zenew.Remove(ints[0] + 1, 1); ints = UpdatePos(zenew, false); }
if (Tokens[ints[1] - 1] == ' ') { zenew.Remove(ints[1] - 1, 1); ints = UpdatePos(zenew, false); }
//reset the array and make the positions easier to get to
Tokens = zenew.ToCharArray();
int OpenP = Array.IndexOf(Tokens, "(");
int CloseP = Array.IndexOf(Tokens, ")");
//prepare the label
string Varname = String.Empty;
for (int i = OpenP + 1; i < CloseP; i++)
{
Varname += Tokens[i];
}
//check if the label has been allocated
string Address = String.Empty;
foreach (Label l in Alloced)
{
if (l.mnemonic == Varname)
{
Address = l.Address;
break;
}
}
//add the label to the List<Label>
Label _l = new Label();
_l.mnemonic = Varname;
_l.Address = Address;
Labeled.Add(_l);
}
private static bool DoRegis(string s) //Do Register Symbol
{
char[] Tokens = new char[s.Length];
Tokens = s.ToCharArray();
// R E G I S T E R S Y M B O L _ ( VARNAME )
int[] ints = new int[2];
ints[0] = Array.IndexOf(Tokens, "(");
ints[1] = Array.IndexOf(Tokens, ")");
//formalize
string zenew = s;
if (Tokens[ints[0] - 1] != ' ') { zenew.Insert(ints[0] - 1, " "); ints = UpdatePos(zenew, false); }
if (Tokens[ints[0] + 1] == ' ') { zenew.Remove(ints[0] + 1, 1); ints = UpdatePos(zenew, false); }
if (Tokens[ints[1] - 1] == ' ') { zenew.Remove(ints[1] - 1, 1); ints = UpdatePos(zenew, false); }
//reset the array and positions
Tokens = zenew.ToCharArray();
int OpenP = Array.IndexOf(Tokens, "(");
int CloseP = Array.IndexOf(Tokens, ")");
string Varname = String.Empty;
for (int i = OpenP + 1; i < CloseP; i++)
{
Varname += Tokens[i];
}
varname = Varname; //for the predicate
Label l = new Label();
l = Array.Find<Label>(Alloced.ToArray(), mypred);
if (l.mnemonic != Varname)
{
System.Windows.Forms.MessageBox.Show("You must allocate space in the program for a symbol before registering it.");
return false;
}
Symbols.Add(l);
return true;
}
private static string varname = String.Empty;
private static bool mypred(Label l)
{
return l.mnemonic == varname;
}
private static bool IsNumeric(string s)
{
foreach (char c in s.ToCharArray())
{
if (!Char.IsNumber(c)) return false;
}
return true;
}
private static bool IsED(string[] script) //is [ENABLE] / [DISABLE]
{
if (script[0] == "[ENABLE]") return true;
return false;
}
private static bool IsLabeled(string s) //checks if the string is labeled (can be used for things like "dog:")
{//note that the string would be "dog" in this case
varname = s;
Label l = new Label();
l = Labeled.Find(mypred);
if (s == l.mnemonic) return true;
return false;
}
private static bool IsAddress(string s) //checks if the string sets an address (like "123123:")
{//note that the string would be "123123" in this case
if (IsNumeric(s)) return true;
return false;
}
private static Label FindLabel(string mnemonic) //to find the label in the List<Label>
{
Label l = new Label();
varname = mnemonic;
l = Array.Find<Label>(Labeled.ToArray(), mypred);
return l;
}
private static string SetCurrentAddress(string s)
{
if (IsAddress(s))
{
return DoStupidHexStuff(s);
}
else //find the label corresponding to the mnemonic we have,
{
Label l = FindLabel(s);
return DoStupidHexStuff(l.Address);
}
}
private static string DoStupidHexStuff(string s)
{
uint u = uint.Parse(s);
return u.ToString("X");
}
private static bool DoInstruction(string _address, string instruction, out int Size)
{
try
{
Size = 0;
List<byte> bytes = new List<byte>(Converter.GetBytes("instruction", _address));
Size = bytes.Count;
IntPtr address = (IntPtr)(int.Parse(_address));
int i;
Main.preader._WriteProcessMemory(address, bytes.ToArray(), out i);
}
catch
{
Size = -1;
return false;
}
return true;
}
private static bool IsHeader(string s)
{
return (s.StartsWith("ALLOC") ||
s.StartsWith("LABEL") ||
s.StartsWith("REGISTERSYMBOL"));
}
public struct Label //public because we need the other things to know about the symbols
{
public string mnemonic;
public string Address; //where the label is stored in memory (so we know where to inject the bytes)
} //it's string because we don't really care
}
}
|
It may not work perfectly--I haven't tested it, and I could probably fix it up a little, but I really don't feel like it. =P
But basically what you do is:
Code: |
string[] AAScript = {
"[ENABLE]"
"alloc(Pancakes,216)",
"label(Pancakes)",
"label(returnhere)",
"",
"400000:",
"jmp Pancakes",
"returnhere:"
"",
"Pancakes:",
"mov eax,BADF00D",
"lea [eax+DEADBEEF]",
"jmp returnhere",
"",
"[DISABLE]",
"400000:"
"mov ecx,80" }
int Spot = 0;
if(!DoAA(AAScript, out Spot)) MessageBox.Show("FAIL");
|
You'll have to include this class:
Code: |
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace YOURNAMESPACE
{
public class ProcessMemoryReader
{
[DllImport("kernel32.dll")]
public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);
[Flags]
public enum ProcessAccessType
{
PROCESS_TERMINATE = (0x0001),
PROCESS_CREATE_THREAD = (0x0002),
PROCESS_SET_SESSIONID = (0x0004),
PROCESS_VM_OPERATION = (0x0008),
PROCESS_VM_READ = (0x0010),
PROCESS_VM_WRITE = (0x0020),
PROCESS_DUP_HANDLE = (0x0040),
PROCESS_CREATE_PROCESS = (0x0080),
PROCESS_SET_QUOTA = (0x0100),
PROCESS_SET_INFORMATION = (0x0200),
PROCESS_QUERY_INFORMATION = (0x0400),
PROCESS_ALL_ACCESS = (0x1F0FFF)
}
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(
IntPtr hProcess,
IntPtr lpAddress,
IntPtr dwSize,
ulong flAllocationType,
ulong flProtect);
public enum AllocationType
{
MEM_COMMIT = 0x1000,
MEM_RESERVE = 0x2000,
MEM_RESET = 0x80000,
}
public enum ProtectionConstants
{
PAGE_EXECUTE = 0X10,
PAGE_EXECUTE_READ = 0X20,
PAGE_EXECUTE_READWRITE = 0X40,
PAGE_EXECUTE_WRITECOPY = 0X80,
PAGE_NOACCESS = 0X01
}
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hObject);
public ProcessMemoryReader()
{
}
/// <summary>
/// Process from which to read
/// </summary>
public Process ReadProcess
{
get
{
return m_ReadProcess;
}
set
{
m_ReadProcess = value;
}
}
private Process m_ReadProcess = null;
private IntPtr m_hProcess = IntPtr.Zero;
public void _OpenProcess()
{
//m_hProcess = ProcessMemoryReaderApi.OpenProcess(ProcessMemoryReaderApi.PROCESS_VM_READ, 1, (uint)m_ReadProcess.Id);
ProcessAccessType access;
access = ProcessAccessType.PROCESS_VM_READ
| ProcessAccessType.PROCESS_VM_WRITE
| ProcessAccessType.PROCESS_VM_OPERATION;
m_hProcess = OpenProcess((uint)access, 1, (uint)m_ReadProcess.Id);
}
public void CloseHandle()
{
int iRetValue;
iRetValue = CloseHandle(m_hProcess);
if (iRetValue == 0)
throw new Exception("CloseHandle failed");
}
public IntPtr Allocate(IntPtr Address, ulong Size)
{
IntPtr res =
VirtualAllocEx(
m_hProcess,
Address,
(IntPtr)Size,
(ulong)AllocationType.MEM_COMMIT | (ulong)AllocationType.MEM_RESERVE,
(ulong)ProtectionConstants.PAGE_EXECUTE_READWRITE);
return res;
}
public void Deallocate(IntPtr Address, ulong Size)
{
VirtualAllocEx(
m_hProcess,
Address,
(IntPtr)Size,
(ulong)AllocationType.MEM_RESET,
(ulong)ProtectionConstants.PAGE_EXECUTE);
}
public void _WriteProcessMemory(IntPtr MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
{
IntPtr ptrBytesWritten;
WriteProcessMemory(m_hProcess, MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);
bytesWritten = ptrBytesWritten.ToInt32();
}
}
}
|
Then init it in your code (assuming that your main place is called "Main")
Code: |
public class Main
{
ProcessMemoryReader preader;
InitPreader(string Procname)
{
preader = new ProcessMemoryReader();
System.Diagnostics.Process[] myprocesses = System.Diagnostics.Process.GetProcessesByName(process);
preader.ReadProcess = myprocesses[0];
preader.OpenProcess();
}
//..... whatever else is here
}
|
Also, there are some things in the AA class that I gave you which require an initialized ProcessMemoryReader (you can change its name, just make sure you change it in both places).
I based my preader class off of gamesguru's C# trainer tut (you can google it), but there are more things that I have which wouldn't be any use to you, most likely, so I just kept them
Anyways, it's a lot of work, but if you're good enough, you can probably stick this all in one class. =P
_________________
|
|