stage2 macho: add empty CodeDirectory blob
parent
d14cd59ef0
commit
79381dc4fb
|
@ -1446,6 +1446,18 @@ pub const CodeDirectory = extern struct {
|
|||
/// Unused (must be zero)
|
||||
spare2: u32,
|
||||
|
||||
///
|
||||
scatterOffset: u32,
|
||||
|
||||
///
|
||||
teamOffset: u32,
|
||||
|
||||
///
|
||||
spare3: u32,
|
||||
|
||||
///
|
||||
codeLimit64: u64,
|
||||
|
||||
/// Offset of executable segment
|
||||
execSegBase: u64,
|
||||
|
||||
|
@ -1453,9 +1465,7 @@ pub const CodeDirectory = extern struct {
|
|||
execSegLimit: u64,
|
||||
|
||||
/// Executable segment flags
|
||||
execSegFlags,
|
||||
|
||||
// end_withExecSeg: [*]u8,
|
||||
execSegFlags: u64,
|
||||
};
|
||||
|
||||
/// Structure of an embedded-signature SuperBlob
|
||||
|
|
|
@ -8,11 +8,39 @@ const mem = std.mem;
|
|||
const testing = std.testing;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
// pub const Blob = union(enum) {
|
||||
// Signature: struct{
|
||||
// inner:
|
||||
// }
|
||||
// };
|
||||
const Blob = struct {
|
||||
inner: macho.CodeDirectory,
|
||||
data: std.ArrayListUnmanaged(u8) = .{},
|
||||
|
||||
fn size(self: Blob) u32 {
|
||||
return self.inner.length;
|
||||
}
|
||||
|
||||
fn write(self: Blob, buffer: []u8) void {
|
||||
assert(buffer.len >= self.inner.length);
|
||||
mem.writeIntBig(u32, buffer[0..4], self.inner.magic);
|
||||
mem.writeIntBig(u32, buffer[4..8], self.inner.length);
|
||||
mem.writeIntBig(u32, buffer[8..12], self.inner.version);
|
||||
mem.writeIntBig(u32, buffer[12..16], self.inner.flags);
|
||||
mem.writeIntBig(u32, buffer[16..20], self.inner.hashOffset);
|
||||
mem.writeIntBig(u32, buffer[20..24], self.inner.identOffset);
|
||||
mem.writeIntBig(u32, buffer[24..28], self.inner.nSpecialSlots);
|
||||
mem.writeIntBig(u32, buffer[28..32], self.inner.nCodeSlots);
|
||||
mem.writeIntBig(u32, buffer[32..36], self.inner.codeLimit);
|
||||
mem.writeIntBig(u8, buffer[36..37], self.inner.hashSize);
|
||||
mem.writeIntBig(u8, buffer[37..38], self.inner.hashType);
|
||||
mem.writeIntBig(u8, buffer[38..39], self.inner.platform);
|
||||
mem.writeIntBig(u8, buffer[39..40], self.inner.pageSize);
|
||||
mem.writeIntBig(u32, buffer[40..44], self.inner.spare2);
|
||||
mem.writeIntBig(u32, buffer[44..48], self.inner.scatterOffset);
|
||||
mem.writeIntBig(u32, buffer[48..52], self.inner.teamOffset);
|
||||
mem.writeIntBig(u32, buffer[52..56], self.inner.spare3);
|
||||
mem.writeIntBig(u64, buffer[56..64], self.inner.codeLimit64);
|
||||
mem.writeIntBig(u64, buffer[64..72], self.inner.execSegBase);
|
||||
mem.writeIntBig(u64, buffer[72..80], self.inner.execSegLimit);
|
||||
mem.writeIntBig(u64, buffer[80..88], self.inner.execSegFlags);
|
||||
}
|
||||
};
|
||||
|
||||
alloc: *Allocator,
|
||||
inner: macho.SuperBlob = .{
|
||||
|
@ -20,16 +48,44 @@ inner: macho.SuperBlob = .{
|
|||
.length = @sizeOf(macho.SuperBlob),
|
||||
.count = 0,
|
||||
},
|
||||
// blobs: std.ArrayList(Blob),
|
||||
blob: ?Blob = null,
|
||||
|
||||
pub fn init(alloc: *Allocator) CodeSignature {
|
||||
return .{
|
||||
.alloc = alloc,
|
||||
// .indices = std.ArrayList(Blob).init(alloc),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn calcAdhocSignature(self: *CodeSignature) !void {}
|
||||
pub fn calcAdhocSignature(self: *CodeSignature) !void {
|
||||
var blob = Blob{
|
||||
.inner = .{
|
||||
.magic = macho.CSMAGIC_CODEDIRECTORY,
|
||||
.length = @sizeOf(macho.CodeDirectory),
|
||||
.version = 0x20400,
|
||||
.flags = 0,
|
||||
.hashOffset = 0,
|
||||
.identOffset = 0,
|
||||
.nSpecialSlots = 0,
|
||||
.nCodeSlots = 0,
|
||||
.codeLimit = 0,
|
||||
.hashSize = 0,
|
||||
.hashType = 0,
|
||||
.platform = 0,
|
||||
.pageSize = 0,
|
||||
.spare2 = 0,
|
||||
.scatterOffset = 0,
|
||||
.teamOffset = 0,
|
||||
.spare3 = 0,
|
||||
.codeLimit64 = 0,
|
||||
.execSegBase = 0,
|
||||
.execSegLimit = 0,
|
||||
.execSegFlags = 0,
|
||||
},
|
||||
};
|
||||
self.inner.length += @sizeOf(macho.BlobIndex) + blob.size();
|
||||
self.inner.count = 1;
|
||||
self.blob = blob;
|
||||
}
|
||||
|
||||
pub fn size(self: CodeSignature) u32 {
|
||||
return self.inner.length;
|
||||
|
@ -38,9 +94,16 @@ pub fn size(self: CodeSignature) u32 {
|
|||
pub fn write(self: CodeSignature, buffer: []u8) void {
|
||||
assert(buffer.len >= self.inner.length);
|
||||
self.writeHeader(buffer);
|
||||
const offset: u32 = @sizeOf(macho.SuperBlob) + @sizeOf(macho.BlobIndex);
|
||||
writeBlobIndex(macho.CSSLOT_CODEDIRECTORY, offset, buffer[@sizeOf(macho.SuperBlob)..]);
|
||||
self.blob.?.write(buffer[offset..]);
|
||||
}
|
||||
|
||||
pub fn deinit(self: *CodeSignature) void {}
|
||||
pub fn deinit(self: *CodeSignature) void {
|
||||
if (self.blob) |*b| {
|
||||
b.data.deinit(self.alloc);
|
||||
}
|
||||
}
|
||||
|
||||
fn writeHeader(self: CodeSignature, buffer: []u8) void {
|
||||
assert(buffer.len >= @sizeOf(macho.SuperBlob));
|
||||
|
@ -49,11 +112,19 @@ fn writeHeader(self: CodeSignature, buffer: []u8) void {
|
|||
mem.writeIntBig(u32, buffer[8..12], self.inner.count);
|
||||
}
|
||||
|
||||
fn writeBlobIndex(tt: u32, offset: u32, buffer: []u8) void {
|
||||
assert(buffer.len >= @sizeOf(macho.BlobIndex));
|
||||
mem.writeIntBig(u32, buffer[0..4], tt);
|
||||
mem.writeIntBig(u32, buffer[4..8], offset);
|
||||
}
|
||||
|
||||
test "CodeSignature header" {
|
||||
var code_sig = CodeSignature.init(testing.allocator);
|
||||
defer code_sig.deinit();
|
||||
|
||||
var buffer: [@sizeOf(macho.SuperBlob)]u8 = undefined;
|
||||
code_sig.writeHeader(buffer[0..]);
|
||||
|
||||
const expected = &[_]u8{ 0xfa, 0xde, 0x0c, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0 };
|
||||
testing.expect(mem.eql(u8, expected[0..], buffer[0..]));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue