stage2 macho: add empty CodeDirectory blob

master
Jakub Konka 2020-11-20 11:05:16 +01:00
parent d14cd59ef0
commit 79381dc4fb
2 changed files with 93 additions and 12 deletions

View File

@ -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

View File

@ -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..]));
}