void UpdateBreakpoints(DkmProcess process, LuaRemoteProcessData processData) { // Can't update breakpoints if we don't have the hook attached if (processData.locations == null) { return; } UpdateHooks(process, processData); int count = processData.activeBreakpoints.Count; if (count > 256) { count = 256; } ulong pointerSize = (ulong)DebugHelpers.GetPointerSize(process); ulong sourceNameAddress = processData.locations.helperBreakSourcesAddress; for (int i = 0; i < count; i++) { ulong dataAddress = processData.locations.helperBreakDataAddress + (ulong)i * 3 * pointerSize; var breakpoint = processData.activeBreakpoints[i]; DebugHelpers.TryWritePointerVariable(process, dataAddress, (ulong)breakpoint.line); if (breakpoint.functionAddress == 0) { Debug.Assert(breakpoint.source != null); byte[] sourceNameBytes = Encoding.UTF8.GetBytes(breakpoint.source); DebugHelpers.TryWriteRawBytes(process, sourceNameAddress, sourceNameBytes); DebugHelpers.TryWriteByteVariable(process, sourceNameAddress + (ulong)sourceNameBytes.Length, 0); ulong currSourceNameAddress = sourceNameAddress; sourceNameAddress += (ulong)sourceNameBytes.Length + 1; DebugHelpers.TryWritePointerVariable(process, dataAddress + pointerSize, 0); DebugHelpers.TryWritePointerVariable(process, dataAddress + pointerSize * 2, currSourceNameAddress); } else { DebugHelpers.TryWritePointerVariable(process, dataAddress + pointerSize, breakpoint.functionAddress); DebugHelpers.TryWritePointerVariable(process, dataAddress + pointerSize * 2, 0); } } DebugHelpers.TryWriteIntVariable(process, processData.locations.helperBreakCountAddress, count); }
void SetupHooks(DkmProcess process, LuaRemoteProcessData processData) { processData.hooksEnabled = true; foreach (var stateKV in processData.knownStates) { var state = stateKV.Value; DebugHelpers.TryWritePointerVariable(process, state.hookFunctionAddress, state.helperHookFunctionAddress); if (processData.luaVersion == 503 || processData.luaVersion == 504) { DebugHelpers.TryWriteIntVariable(process, state.hookMaskAddress, 7); // LUA_HOOKLINE | LUA_HOOKCALL | LUA_HOOKRET } else { DebugHelpers.TryWriteByteVariable(process, state.hookMaskAddress, 7); // LUA_HOOKLINE | LUA_HOOKCALL | LUA_HOOKRET } DebugHelpers.TryWriteIntVariable(process, state.hookBaseCountAddress, 0); DebugHelpers.TryWriteIntVariable(process, state.hookCountAddress, 0); // Lua 5.4 has to update 'trap' flag for all Lua call stack frames if (processData.luaVersion == 504) { ulong?callInfo = DebugHelpers.ReadPointerVariable(process, state.stateAddress + state.setTrapStateCallInfoOffset); while (callInfo.HasValue && callInfo.Value != 0) { var callStatus = DebugHelpers.ReadShortVariable(process, callInfo.Value + state.setTrapCallInfoCallStatusOffset); if (callStatus.HasValue && (callStatus.Value & (int)CallStatus_5_4.C) == 0) { if (!DebugHelpers.TryWriteIntVariable(process, callInfo.Value + state.setTrapCallInfoTrapOffset, 1)) { break; } } callInfo = DebugHelpers.ReadPointerVariable(process, callInfo.Value + state.setTrapCallInfoPreviousOffset); } } } }
void RemoveHooks(DkmProcess process, LuaRemoteProcessData processData) { processData.hooksEnabled = false; foreach (var stateKV in processData.knownStates) { var state = stateKV.Value; DebugHelpers.TryWritePointerVariable(process, state.hookFunctionAddress, 0); if (processData.luaVersion == 503 || processData.luaVersion == 504) { DebugHelpers.TryWriteIntVariable(process, state.hookMaskAddress, 0); } else { DebugHelpers.TryWriteByteVariable(process, state.hookMaskAddress, 0); } DebugHelpers.TryWriteIntVariable(process, state.hookBaseCountAddress, 0); DebugHelpers.TryWriteIntVariable(process, state.hookCountAddress, 0); } }