public PatternScanner(MemHelper memhelper) { _logger = Locator.Current.GetService <ILogger>(); _memhelper = memhelper; _baseAddress = memhelper.BaseAddress; var dosHeaders = memhelper.Read <IMAGE_DOS_HEADER>(_baseAddress); _logger.Write($"dosHeaders.isvalid{dosHeaders.isValid}", LogLevel.Info); if (dosHeaders.isValid) { var ntHeaders = memhelper.Read <IMAGE_NT_HEADERS64>(_baseAddress + dosHeaders.e_lfanew); SizeOfCode = ntHeaders.OptionalHeader.SizeOfCode; CodeBase = ntHeaders.OptionalHeader.BaseOfCode; _dataLength = CodeBase + SizeOfCode; _data = memhelper.ReadBytes(_baseAddress, (int)_dataLength); _logger.Write($"SizeofCode:{SizeOfCode} CodeBase:{CodeBase}", LogLevel.Info); } }
public ushort GetAlertOpCode() { var jumpTableIndexOffset = patternscanner.FindSingle("8D 42 ? 3D ? ? ? ? 0F 87 ? ? ? ? 4C 8D 05 ? ? ? ? 48 98 48", ptr => { byte value = memhelper.Read <byte>(ptr + 0x2); _logger.Write($"raw offset {value}", LogLevel.Warn); return((value ^ 0x80) - 0x80); }); _logger.Write($"Jumptable index offset 0x{(int)jumpTableIndexOffset:X}", LogLevel.Warn); var functionptr = patternscanner.FindSingle("48 89 5C 24 ? 57 48 83 EC 20 80 79 55 00"); var functionRef = patternscanner.FindFunctionCall(functionptr); _logger.Write($"Found function call of 0x{(ulong)functionptr:X} at 0x{(ulong)functionRef:X}", LogLevel.Warn); //Read backwards until 0xCC CC is found to get the start of the queue function var memory = memhelper.ReadBytes(functionRef - 0x200, 0x205); //_logger.Write("read bytes",LogLevel.Warn); Array.Reverse(memory); //_logger.Write(ByteArrayToString(memory),LogLevel.Warn); functionptr = IntPtr.Zero; for (int i = 0; i < memory.Length; i++) { //if (memory[i] == 0xCC && memory[i - 1] == 0xCC && memory[i - 2] == 0xCC && memory[i - 3] == 0xCC) var m = BitConverter.ToUInt32(memory, i); //_logger.Write($"Fo 0x{m:X} {i}", LogLevel.Warn); if (m == 0xCCCCCCCC) { functionptr = functionRef - i + 5; _logger.Write($"functionRef:0x{(ulong)functionRef:X} functionptr:0x{(ulong)functionptr:X} {i}", LogLevel.Warn); break; } } //_logger.Write("Finished loop", LogLevel.Warn); functionRef = patternscanner.FindFunctionCall(functionptr); _logger.Write($"Found function call of 0x{(ulong)functionptr:X} at 0x{(ulong)functionRef:X}", LogLevel.Warn); //Go back 0x13 bytes from the function call location to get where the jumptable points to var jumplocation = functionRef - 0x13; var jumptablevalues = patternscanner.FindSingle("41 8B 8C 80 ? ? ? ? 49 03 C8 FF E1 B9 ? ? ? ? ? ? ? ? ? ? 48", ptr => { var jumptableAddress = memhelper.BaseAddress + memhelper.Read <int>(ptr + 4); _logger.Write($"Found jumptable of 0x{(ulong)jumptableAddress:X} at 0x{(ulong)ptr:X}", LogLevel.Warn); //Just read a large number of values, its ~900 ingame so set a larger static value so we don't need another pattern return(memhelper.Read <int>(jumptableAddress, 1024)); }); for (int i = 0; i < jumptablevalues.Length; i++) { //_logger.Write($"{(ulong)(memhelper.BaseAddress + jumptablevalues[i]):X}", LogLevel.Warn); if (memhelper.BaseAddress + jumptablevalues[i] == jumplocation) { if (jumpTableIndexOffset < 0) { return((ushort)(i - jumpTableIndexOffset)); } return((ushort)(i + jumpTableIndexOffset)); } } _logger.Write($"Failed to find alert opcode", LogLevel.Warn); throw new Exception("Failed to find alert opcode"); }