diff --git a/bin/install.pike b/bin/install.pike
index e971e83f4f39ba415c5bb393307add4eca06baf4..76f8aa2902b6d75c86bee3599aef1cbed05ca495 100644
--- a/bin/install.pike
+++ b/bin/install.pike
@@ -2582,6 +2582,135 @@ void dump_modules()
   status_clear(1);
 }
 
+// Recalculate adhoc signature hashes on macOS after updating the master cookie
+array(int) find_macho_signature(Stdio.File f)
+{
+  int magic;
+  string endian;
+  f->seek(0);
+  sscanf(f->read(4), "%4c", magic);
+  if (magic == 0xfeedfacf) {
+    endian = "";
+  } else if (magic == 0xcffaedfe) {
+    endian = "-";
+  } else
+    return 0;
+  array(int) header = array_sscanf(f->read(4*7), ("%"+endian+"4c")*7);
+  if (sizeof(header) < 7)
+    return 0;
+  int ncmds = header[3];
+  for(int i=0; i<ncmds; i++) {
+    int cmdstart = f->tell();
+    array(int) command = array_sscanf(f->read(4*2), ("%"+endian+"4c")*2);
+    if (sizeof(command) < 2)
+      return 0;
+    if (command[0] == 0x1d && command[1] >= 8) {
+      array(int) sig = array_sscanf(f->read(4*2), ("%"+endian+"4c")*2);
+      if (sizeof(sig) == 2)
+        return sig;
+    }
+    f->seek(cmdstart + command[1]);
+  }
+  return 0;
+}
+
+int find_superblob_code_directory(Stdio.File f, int sb_offs, int sb_len)
+{
+  if (sb_len < 4*3)
+    return 0;
+  f->seek(sb_offs);
+  array(int) header = array_sscanf(f->read(4*3), "%4c"*3);
+  if (sizeof(header) < 3 || header[0] != 0xfade0cc0 || header[1] > sb_len)
+    return 0;
+  sb_len = header[1];
+  int nslot = header[2];
+  if (sb_len < 4*3 + 4*2*nslot)
+    return 0;
+  for (int i=0; i<nslot; i++) {
+    array(int) slot = array_sscanf(f->read(4*2), "%4c"*2);
+    if (sizeof(slot) < 2)
+      return 0;
+    if (slot[0] == 0)
+      return slot[1];
+  }
+  return 0;
+}
+
+array(int) find_code_directory_hash_layout(Stdio.File f, int sb_offs, int sb_len, int cd_offs)
+{
+  if (cd_offs + 40 > sb_len)
+    return 0;
+  f->seek(sb_offs + cd_offs);
+  array(int) header = array_sscanf(f->read(40), "%4c"*9 + "%1c"*4);
+  if (sizeof(header) < 13 || header[0] != 0xfade0c02 ||
+      header[1] < 40 || cd_offs + header[1] > sb_len)
+    return 0;
+  int hash_offs = header[4];
+  int n_code_slots = header[7];
+  int code_limit = header[8];
+  int hash_size = header[9];
+  int hash_type = header[10];
+  int page_size = header[12];
+  if (hash_offs + n_code_slots * hash_size > sb_len)
+    return 0;
+  return ({ sb_offs + cd_offs + hash_offs, hash_type, hash_size,
+            n_code_slots, page_size, code_limit });
+}
+
+void update_signature_hashes(Stdio.File f, int hash_offs, int hash_type,
+                             int hash_size, int n_code_slots, int page_size,
+                             int code_limit)
+{
+  Crypto.Hash hash;
+  switch(hash_type) {
+#if constant(Crypto.SHA256)
+  case 2:
+    hash = Crypto.SHA256;
+    break;
+#endif
+  default:
+    error("Hash type %d not supported!\n", hash_type);
+  }
+  if (hash_size != hash()->digest_size())
+    error("Error wrong digest size %d (!= %d) for hash type %d\n",
+          hash_size, hash()->digest_size(), hash_type);
+  f->seek(hash_offs);
+  array(string) hashes = f->read(n_code_slots * hash_size) / hash_size;
+  if (sizeof(hashes) < n_code_slots)
+    n_code_slots = sizeof(hashes);
+  int pos = 0;
+  for (int i=0; i<n_code_slots; i++) {
+    string data = "";
+    if (pos < code_limit) {
+      int sz = 1 << page_size;
+      if (pos + sz > code_limit)
+        sz = code_limit - pos;
+      f->seek(pos);
+      data = f->read(sz);
+      pos += sizeof(data);
+      if (sizeof(data) < sz)
+        code_limit = pos;
+    }
+    hashes[i] = hash()->update(data)->digest();
+  }
+  f->seek(hash_offs);
+  f->write(hashes * "");
+}
+
+void fix_macos_adhoc_signature(Stdio.File f)
+{
+  array(int) macho_sig = find_macho_signature(f);
+  if (macho_sig) {
+    int sb_code_dir = find_superblob_code_directory(f, @macho_sig);
+    if (sb_code_dir) {
+      array(int) hash_layout = find_code_directory_hash_layout(f, @macho_sig,
+                                                               sb_code_dir);
+      if (hash_layout)
+        update_signature_hashes(f, @hash_layout);
+    }
+  }
+}
+
 void finalize_pike()
 {
   pike=combine_path(exec_prefix,"pike");
@@ -2637,6 +2766,7 @@ void finalize_pike()
       Stdio.File f=Stdio.File(pike_bin_file,"rw");
       f->seek(pos+sizeof(MASTER_COOKIE));
       f->write(combine_path(lib_prefix,"master.pike"));
+      fix_macos_adhoc_signature(f);
       f->close();
       status("Finalizing",pike_bin_file,"done");
       if(install_file(pike_bin_file,pike,0755)) {