authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-30 14:10:11+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-30 21:08:30+02:00
logd2f013085523436b51023f7d28d52a859b70a4b3
tree4ce7652b3f37aa63016d0c56009b7fecb685476e
parent39d63036441841fb81eebda97fb2932e5c3f79c4

coff: make sure we correctly slide relocation target when resolving


2 files changed, 15 insertions(+), 17 deletions(-)

src/link/Coff.zig+14-16
......@@ -788,10 +788,9 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void {
788788
789789 if (self.base.child_pid) |handle| {
790790 const vaddr = sym.value + (self.hot_state.loaded_base_address orelse self.getImageBase());
791 log.warn("hcs: writing to memory at address {x}", .{vaddr});
792 try debugMem(self.base.allocator, handle, vaddr, code);
791 log.debug("writing to memory at address {x}", .{vaddr});
793792 if (section.header.flags.MEM_WRITE == 0) {
794 log.warn(" page not mapped for write access; re-mapping...", .{});
793 log.debug("page not mapped for write access; re-mapping...", .{});
795794 try writeMemProtected(handle, vaddr, code);
796795 } else {
797796 try writeMem(handle, vaddr, code);
......@@ -859,7 +858,7 @@ fn getProcessBaseAddress(handle: std.ChildProcess.Id) !u64 {
859858 &peb_nread,
860859 ) == 0) {
861860 const err = std.os.windows.kernel32.GetLastError();
862 log.warn("hcs: reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) });
861 log.warn("reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) });
863862 return error.FailedToReadPebForProcess;
864863 }
865864 if (peb_nread != @sizeOf(std.os.windows.PEB)) return error.InputOutput;
......@@ -880,14 +879,14 @@ fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, vaddr: u64, code:
880879 &nread,
881880 ) == 0) {
882881 const err = std.os.windows.kernel32.GetLastError();
883 log.warn("hcs: reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) });
882 log.warn("reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) });
884883 }
885884 if (nread != code.len) {
886 log.warn("hcs: reading from process memory InputOutput error: read != requested: {x} != {x}", .{ nread, code.len });
885 log.warn("reading from process memory InputOutput error: read != requested: {x} != {x}", .{ nread, code.len });
887886 }
888887
889 log.warn("in memory: {x}", .{std.fmt.fmtSliceHexLower(buffer)});
890 log.warn("to write: {x}", .{std.fmt.fmtSliceHexLower(code)});
888 log.debug("in memory: {x}", .{std.fmt.fmtSliceHexLower(buffer)});
889 log.debug("to write: {x}", .{std.fmt.fmtSliceHexLower(code)});
891890}
892891
893892fn writeMemProtected(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void {
......@@ -896,16 +895,15 @@ fn writeMemProtected(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8)
896895 var old_prot: std.os.windows.DWORD = undefined;
897896 if (VirtualProtectEx(handle, pvaddr, code.len, new_prot, &old_prot) == 0) {
898897 const err = std.os.windows.kernel32.GetLastError();
899 log.warn("hcs: making page(s) writeable failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) });
898 log.warn("making page(s) writeable failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) });
900899 return;
901900 }
902 log.warn("old = {x}, new = {x}", .{ old_prot, new_prot });
903901 try writeMem(handle, vaddr, code);
904902 // TODO: We can probably just set the pages writeable and leave it at that without having to restore the attributes.
905903 // For that though, we want to track which page has already been modified.
906904 if (VirtualProtectEx(handle, pvaddr, code.len, old_prot, &new_prot) == 0) {
907905 const err = std.os.windows.kernel32.GetLastError();
908 log.warn("hcs: restoring page(s) attributes failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) });
906 log.warn("restoring page(s) attributes failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) });
909907 }
910908}
911909
......@@ -919,10 +917,10 @@ fn writeMem(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void {
919917 &nwritten,
920918 ) == 0) {
921919 const err = std.os.windows.kernel32.GetLastError();
922 log.warn("hcs: writing to process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) });
920 log.warn("writing to process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) });
923921 }
924922 if (nwritten != code.len) {
925 log.warn("hcs: writing to process memory InputOutput error: written != requested: {x} != {x}", .{ nwritten, code.len });
923 log.warn("writing to process memory InputOutput error: written != requested: {x} != {x}", .{ nwritten, code.len });
926924 }
927925}
928926
......@@ -973,15 +971,15 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void {
973971}
974972
975973pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void {
976 log.warn("hcs: attaching to process with handle {*}", .{handle});
974 log.debug("attaching to process with handle {*}", .{handle});
977975 self.hot_state.loaded_base_address = getProcessBaseAddress(handle) catch |err| {
978 log.warn("hcs: failed to get base address for the process with error: {s}", .{@errorName(err)});
976 log.warn("failed to get base address for the process with error: {s}", .{@errorName(err)});
979977 return;
980978 };
981979}
982980
983981pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void {
984 log.warn("hcs: detaching from process with handle {*}", .{handle});
982 log.debug("detaching from process with handle {*}", .{handle});
985983 self.hot_state.loaded_base_address = null;
986984}
987985
src/link/Coff/Relocation.zig+1-1
......@@ -92,7 +92,7 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, coff_file:
9292 const ctx: Context = .{
9393 .source_vaddr = source_vaddr,
9494 .target_vaddr = target_vaddr_with_addend,
95 .image_base = coff_file.getImageBase(),
95 .image_base = coff_file.hot_state.loaded_base_address orelse coff_file.getImageBase(),
9696 .code = code,
9797 .ptr_width = coff_file.ptr_width,
9898 };