public static int CopyMemory(UBytePtr dest, UBytePtr src, int size) { return(UArrayUtils.CopyMemory(dest.ToIntPtr(), 0, src.ToIntPtr(), 0, size)); }
public AVariableType FindTypeOfData(UIntPtr address, UBytePtr buf, int size, AFindTypeOption findOption = AFindTypeOption.None) { var v = 0UL; //check if it matches a string var result = AVariableType.DWord; try { var floatHasSeparator = false; int i; if (!UEnumUtils.HasFlag(findOption, AFindTypeOption.NoString)) { var isString = true; var couldBeStringCounter = true; i = 0; while (i < 4) { //check if the first 4 characters match with a standard ascii values (32 to 127) if (i < size) { if (buf[i] < 32 || buf[i] > 127) { isString = false; if (i > 0) { couldBeStringCounter = false; } if (!couldBeStringCounter) { break; } } } else { isString = false; couldBeStringCounter = false; } i += 1; } if (isString) { result = AVariableType.String; return(result); } if (couldBeStringCounter && size > 4 && (buf[4] >= 32 || buf[4] <= 127)) //check if the 4th byte of the 'string' is a char or not { //this is a string counter result = AVariableType.Byte; return(result); } //check if unicode isString = true; i = 0; if (size >= 8) { while (i < 8) { //check if the first 4 characters match with a standard ascii values (32 to 127) if (buf[i] < 32 || buf[i] > 127) { isString = false; break; } i += 1; if (buf[i] != 0) { isString = false; break; } i += 1; } } else { isString = false; } if (isString) { result = AVariableType.UnicodeString; return(result); } } i = (int)(address.ToUInt64() % 4); if (size == 4 || size == 8) { i = 0; //skip this test, it's a known size data block } switch (i) { case 1: //1 byte result = AVariableType.Byte; return(result); case 2: case 3: //2 byte if (buf.ReadUInt16() < 255 || buf.ReadUInt16() % 10 > 0) //less than 2 byte or not dividable by 10 { result = AVariableType.Byte; } else { result = AVariableType.Word; } return(result); } if (size >= Proc.PointerSize) { //named addresses int n; if (Proc.IsX64) { if ((int)(address.ToUInt64() % 8) == 0) { AStringUtils.Val("0x" + SymbolHandler.GetNameFromAddress((UIntPtr)buf.ReadUInt64(), true, true, false, null, out _, 8, false), out v, out n); } else { n = 0; } } else { AStringUtils.Val("0x" + SymbolHandler.GetNameFromAddress((UIntPtr)buf.ReadUInt32(), true, true, false, null, out _, 8, false), out v, out n); } if (n > 0) //named { result = AVariableType.Pointer; return(result); } } String x; if (size >= 2 && size < 4) { result = AVariableType.Word; return(result); } else if (size == 1) { result = AVariableType.Byte; return(result); } else if (Math.Abs(buf.ReadFloat()) > Single.Epsilon) // todo this seems unreliable since anything can be a single.. { x = buf.ReadFloat().ToString(CultureInfo.InvariantCulture); if (AStringUtils.Pos("E", x) == -1) //no exponent { //check if the value isn't bigger or smaller than 100000 or smaller than -100000 if (AMathUtils.InRange(buf.ReadFloat(), -100000.0, 100000.0)) { if (AStringUtils.Pos(AConstants.DecimalSeparator, x) != -1) { floatHasSeparator = true; } result = AVariableType.Single; if (x.Length <= 4 || !floatHasSeparator) { return(result); //it's a full floating point value or small enough to fit in 3 digits and a separator (1.01, 1.1 ....) } } } } if (!UEnumUtils.HasFlag(findOption, AFindTypeOption.NoDouble)) { if (size >= 8) //check if a double can be used { if (Math.Abs(buf.ReadDouble()) > Double.Epsilon) // todo this seems unreliable since anything can be a double.. { x = buf.ReadDouble().ToString(CultureInfo.InvariantCulture); if (AStringUtils.Pos("E", x) == -1) //no exponent { //check if the value isn't bigger or smaller than 100000 or smaller than -100000 if (buf.ReadDouble() < 100000 && buf.ReadDouble() > -100000) { if (result == AVariableType.Single) { if (buf.ReadDouble() > buf.ReadFloat()) { return(result); //float has a smaller value } } result = AVariableType.Double; if (buf.ReadUInt32() != 0) { x = buf.ReadFloat().ToString(CultureInfo.InvariantCulture); if (AStringUtils.Pos("E", x) == -1) //no exponent { //if 4 bytes after this address is a float then override this double to a single type if (FindTypeOfData(address + 4, buf.Shift(4), size - 4) == AVariableType.Single) { result = AVariableType.Single; } } } return(result); } } } } } //check if it's a pointer if (Proc.IsX64) { if (((int)(address.ToUInt64() % 8) == 0) & AMemoryHelper.IsReadable(Proc.Handle, ((UIntPtr)buf.ReadUInt64()).ToIntPtr())) { result = AVariableType.Pointer; return(result); } } else { if (AMemoryHelper.IsReadable(Proc.Handle, ((UIntPtr)buf.ReadUInt32()).ToIntPtr())) { result = AVariableType.Pointer; // if inrange(pdword(@buf[0])^, $3d000000, $44800000)=false then //if it's not in this range, assume it's a pointer. Otherwise, could be a float return(result); } } // todo implement custom type //if customtype is not nil check if the dword is humanreadable or not // if ((customtype != nil) && (result == vtdword) && (ishumanreadableinteger(pdword(&buf[0])) == false)) // { // //not human readable, see if there is a custom type that IS human readable // for (i = 0; i <= customtypes.count - 1; i++) // { // if (tcustomtype(customtypes[i]).scriptusesfloat) // { // //float check // f = tcustomtype(customtypes[i]).convertdatatofloat(&buf[0], address); // x = floattostr(f); // // if ((pos("E", x) == 0) && (f != 0) & inrange(f, -100000.0, 100000.0)) // { // result = vtcustom; // customtype = customtypes[i]; // // if (pos(defaultformatsettings.decimalseparator, x) == 0) // flush(); //found one that has no decimal seperator // // } // } // else // { // //dword check // if (ishumanreadableinteger(tcustomtype(customtypes[i]).convertdatatointeger(&buf[0], address))) // { // result = vtcustom; // customtype = customtypes[i]; // flush(); // } // } // } // } } finally { // todo implement custom types // if (assigned(onautoguessroutine)) // result = onautoguessroutine(address, result); } return(result); }
static void Main(string[] args) { //test.a(); //var Brackets = new ACharArray('(', ')', '[', ']', '{', '}'); //var StdWordDelims = new ACharArray(',', '.', ';', '/', '\\', ':', '\'', '"', '`', '(', ')', '[', ']', '{', '}'); //StdWordDelims.AddRange(Brackets.TakeAll()); //StdWordDelims.AddRange(ACharUtils.Range('\0', ' ').TakeAll()); // //Console.WriteLine("done"); var m = new AProcessSharp(System.Diagnostics.Process.GetProcessesByName("pacwin")[0], AMemoryType.Remote); UTokenSp.Activate(); AAsmTools.InitTools(new ASymbolHandler()); AAsmTools.SymbolHandler.Process = m; var a = AAsmTools.Assembler; var b1 = new AByteArray(); //var m2 = new AProcessSharp(System.Diagnostics.Process.GetCurrentProcess(), AMemoryType.Remote); a.SymbolHandler.Process = m; var aa = AAsmTools.AutoAssembler; //var result = a.Assemble("mov eax, [edx+esi+66]", 0x400300, b1); // E9 FB 01 00 00 //var result = a.Assemble("mov rax,[1122334455778899]", 0x400300, b1); // E9 FB 01 00 00 //Console.WriteLine("Result: " + result); //Console.WriteLine("Bytes:"); //Console.WriteLine(UBinaryUtils.Expand(b1.TakeAll())); // // var d = AAsmTools.Disassembler; //var sd = ""; //using (var pt = new UBytePtr(b1.TakeAll())) //{ // var ptt = pt.ToIntPtr().ToUIntPtr(); // d.Disassemble(ref ptt, ref sd); //} //Console.WriteLine(d.LastDisassembleData.Prefix + ' ' + d.LastDisassembleData.OpCode + ' ' + d.LastDisassembleData.Parameters); var bi = AAsmTools.ByteInterpreter; var bp = m.Memory.Read((IntPtr)0x411C88, 32); using (var bip = new UBytePtr(bp)) { Console.WriteLine("Found dataType: " + bi.FindTypeOfData((UIntPtr)0x411C88, bip, 8)); Console.WriteLine("Found dataType: " + bi.DataToString(bp, 8, AVariableType.Double)); } // aa.Assembler.SymHandler.Process = m; // var cd = @" // 400300: // mov rax, [411c88] // mov rax, dword ptr[11223344556677] // ".Trim(); // var codex = new ARefStringArray(); // codex.Assign(UStringUtils.GetLines(cd).ToArray()); // aa.RemoveComments(codex); // // var b = aa.Assemble(aa.SelfSymbolHandler.Process, codex); d.IsDataOnly = false; // d.Is64Bit = true; // d.SymbolHandler.Process = m; var s1 = ""; // var bytes = new UBytePtr(b[0].Bytes.TakeAll()); // //var ptr = bytes.ToIntPtr().ToUIntPtr(); // var ptr = (UIntPtr)0x40230F; var i = 30; while (i-- > 0) { try { var dis = d.Disassemble(ref ptr, ref s1); var cl = d.LastDisassembleData.Prefix + ' ' + d.LastDisassembleData.OpCode + ' ' + d.LastDisassembleData.Parameters; var dec = d.DecodeLastParametersToString(); //Console.WriteLine(cl + " ; " + dec); d.SplitDisassembledString(dis, false, out var address, out var bytes, out var opcode, out var special); Console.WriteLine($"0x{address.PadRight(8)} {bytes.PadRight(20)} {opcode} {special} ; {dec}"); } catch (Exception e) { Console.WriteLine("Error " + e.Message); Console.WriteLine(e.Source); Console.WriteLine(e.StackTrace); break; } } // Console.ReadKey(); // Environment.Exit(1); a.SymbolHandler.Process = m; var cc = @" [ENABLE] 400300: mov edx, dword ptr[411c88] reassemble(40230f); reassemble(pacwin.exe+2379); cat: reassemble(pacwin.exe+237C); call messageboxa jmp cat 400314: [DISABLE] ".Trim(); var code = new ARefStringArray(); code.Assign(UStringUtils.GetLines(cc).ToArray()); aa.RemoveComments(code); var scr = new AScriptBytesArray(); var info = new ADisableInfo(); var ret = aa.AutoAssemble(m, code, false, true, false, false, info, false, scr); Console.WriteLine("Loaded 2"); Console.WriteLine("Result: " + ret); aa.AutoAssemble(m, code, false, true, false, false, info, true, scr); Console.WriteLine("Loaded 3"); foreach (var o in scr) { Console.WriteLine("Line: " + o.Type + " " + o.Address.ToUInt64().ToString("X") + " " + AStringUtils.BinToHexStr(o.Bytes.TakeAll())); } // var f = new AAssemblyFactory(m, new ASharpAsm()); // f.Inject( // new[] // { // "mov, eax 7", // "push 0", // "add esp, 4", // "retn" // }, // (IntPtr) 0x400310); // // var v = f.Execute<int>((IntPtr)0x400310); // Console.WriteLine("Return: " + v); //f.InjectAndExecute( // new[] // { // "alloc(storage, 1000)", // "label(caption)", // "label(message)", // "push 0", // "push caption", // "push message", // "push 0", // "call MessageBoxA", // "push 0", // "add esp, 4", // "retn", // // storage zone // "storage:", // "caption:", // " db 'caption', 00", // "message:", // " db 'message', 00", // }, // (IntPtr)0x400300); Console.ReadKey(); //aa.AutoAssemble(m, code, false, false, false, false, info, false, scr); Environment.Exit(1); }
public String DataToString(UBytePtr buf, int size, AVariableType varType, Boolean clean = false) { String result; switch (varType) { case AVariableType.Byte: { if (clean) { result = AStringUtils.IntToHex(buf[0], 2); } else { result = "(byte)" + AStringUtils.IntToHex(buf[0], 2) + '(' + buf[0] + ')'; } break; } case AVariableType.Word: { if (clean) { result = AStringUtils.IntToHex(buf.ReadUInt16(), 4); } else { result = "(word)" + AStringUtils.IntToHex(buf.ReadUInt16(), 4) + '(' + buf.ReadUInt16() + ')'; } break; } case AVariableType.DWord: { if (clean) { result = AStringUtils.IntToHex(buf.ReadUInt32(), 8); } else { result = "(dword)" + AStringUtils.IntToHex(buf.ReadUInt32(), 8) + '(' + buf.ReadUInt32() + ')'; } break; } case AVariableType.QWord: { if (clean) { result = AStringUtils.IntToHex(buf.ReadUInt64(), 16); } else { result = "(qword)" + AStringUtils.IntToHex(buf.ReadUInt64(), 16) + '(' + buf.ReadUInt64() + ')'; } break; } case AVariableType.Single: { if (clean) { result = UStringUtils.Sprintf("%.2f", buf.ReadFloat()); } else { result = "(float)" + UStringUtils.Sprintf("%.2f", buf.ReadFloat()); } break; } case AVariableType.Double: { if (clean) { result = UStringUtils.Sprintf("%.2f", buf.ReadDouble()); } else { result = "(double)" + UStringUtils.Sprintf("%.2f", buf.ReadDouble()); } break; } case AVariableType.String: { using (var p = new UBytePtr(size + 1)) { AArrayUtils.CopyMemory(p, buf, size); p[size] = 0; result = UBitConverter.UnpackSingle("z1", 0, p.ToByteArray()); } break; } case AVariableType.UnicodeString: { using (var p = new UBytePtr(size + 2)) { AArrayUtils.CopyMemory(p, buf, size); p[size] = 0; p[size + 1] = 0; result = UBitConverter.UnpackSingle("z7", 0, p.ToByteArray()); } break; } case AVariableType.Pointer: { UIntPtr a; if (Proc.IsX64) { a = (UIntPtr)buf.ReadUInt64(); } else { a = (UIntPtr)buf.ReadUInt32(); } if (clean) { result = ""; } else { result = "(pointer)"; } result += SymbolHandler.GetNameFromAddress(a, true, true, false); break; } default: { result = "(...)"; for (var i = 0; i <= Math.Min(size, 8) - 1; i++) { result = result + AStringUtils.IntToHex(buf[i], 2) + ' '; } break; } } return(result); }