Okay, so here is my edited script with the now fully functional method of finding the magic.
I've made a another modification in that it now patches cpuids in both 32 and 64bit binaries. This wasn't needed before the release of the voodoo XNU, but now AMD machines can run in 64bit mode.

So you can now run OSX on AMD in 64bit using the voodoo XNU with on the fly cpuid patching in conjunction with dsmos.kext (on the fly decrypting) or the like, or you can patch/decrypt using this script and lighten the load a little bit, the choice is yours.
To run the script you would need otool, size and apb_decrypt in a directory named /Library/Application Support/HexleySupport. Better just to put them in your PATH and edit the script. otool and size are part of the Xcode Developer Tools and can be downloaded from Apple. apb_decrypt is in my sig, everything else the script uses (grep... etc.)is part of the standard OSX install.
CODE
#!/bin/sh
# AMDbinPatch.sh
#
#
# Created by incompetence and ignorance on a cold day in hell.
# Copyright 2008 __MyAss__. All rights reserved.
SupportFiles="/Library/Application Support/HexleySupport"
DispLine="----------------------------------------------------------------------------"
disptime ()
{
time=`date "+%H:%M:%S"`
echo "${time}"
return 0
}
removeCpuids () # $1 The path to the resource folder - $2 The name of the volume to be patched
{
if [ ! -d "${1}" ] || [ ! -d "/Volumes/${2}" ] || [ "${2}" = "" ]; then
{
echo "usage: removeCpuids <\$1> <\$2>
\$1 = The path to the resource folder (this folder must contain \"otool\" and \"apb_decrypt\")
\$2 = The volume name to be patched"
return 1
}
else
{
echo; echo $DispLine
disptime;echo "Removing CPUIDs and decrypting apple-protected binaries for AMD compatibility."
echo
for targets in /Applications /Library /System /bin /private /sbin /usr
do
find "/Volumes/${2}${targets}" -type f -perm +111 | while read binaryPath # Find candidate binaries.
do
for arch in "i386" "x86_64" # Since the release of the voodoo XNU it is no possible to run AMD in 64 bit, so we now check 32 and 64 bit binaries.
do
protected=""
protected=`"${1}"/otool -arch ${arch} -lv "${binaryPath}" 2>/dev/null | grep "flags PROTECTED_VERSION_1"` # Is the candidate binary encrypted.
if [ "${protected}" != "" ];then
{
if [ "${arch}" = "x86_64" ];then
lipo -thin i386 -o "${binaryPath}" "${binaryPath}" >& /dev/null # At the moment apb_decrypt will only decrypt i386 binaries. At the time of writing Apple haven't (to my knowledge) released any binary were the x86_64 object encrypted so this function is unnecessary, but I have included it as a precaution.
fi
echo; echo "Decrypting apple-protected binary:"
echo "${binaryPath}"
mv "${binaryPath}" "${binaryPath}.original"
"${1}"/apb_decrypt "${binaryPath}.original" "${binaryPath}" # Decrypt the binary.
if [ -f "${binaryPath}" ]; then
rm -rf "${binaryPath}.original"
else
{
mv "${binaryPath}.original" "${binaryPath}"
echo "ERROR: failed to decrypt binary ${binaryPath}"
return 1
}
fi
}
fi
vmaddrCpuids=""
vmaddrCpuids=`"${1}"/otool -arch ${arch} -tv "${binaryPath}" 2>/dev/null | grep "cpuid" | awk '{print $1}'` # If the binary contains cpuids find the offset of virtual memory address of cpuids in base 16
if [ "${vmaddrCpuids}" != "" ];then
{
echo; echo "Patching CPUID protected binary:"
echo "${binaryPath}"
cefaedfe=`"${1}"/otool -arch ${arch} -fv "${binaryPath}" | grep -A6 ${arch} | grep offset | awk '{print $2}'` # Offset of start architecture (the CEFAEDFE magic) relative to object file in base 10 (will be zero if the binary isn't FAT)
textSection=`"${1}"/size -arch ${arch} -m -l -x "${binaryPath}" | grep -A7 __TEXT | grep __text | awk '{print $7}' | sed 's/)//'` # Offset of __text section relative to object file in base 10
vmaddrTextSection=`"${1}"/size -arch ${arch} -m -l -x "${binaryPath}" | grep -A7 __TEXT | grep __text | awk '{print $5}'` # Offset of virtual memory address of __text section in base 16
for vmaddrCpuid in ${vmaddrCpuids}
do
vmaddrCpuid="0x${vmaddrCpuid}" # Format the base 16 value with leading 0x
cpuid=`echo $((${cefaedfe}+${textSection}+${vmaddrCpuid}-${vmaddrTextSection}))` # Offset of address of CPUID in base 10
cpuid=`echo "obase=16;ibase=10; $cpuid" | bc` # Offset of address of CPUID in base 16
cpuidx="0x${cpuid}" # Format the base 16 value with leading 0x
currentHex=`"${1}"/xxd -s "${cpuidx}" -ps -l 2 "${binaryPath}"`
if [ "${currentHex}" = "0fa2" ]; then
{
echo "${cpuid}: cdfb" | "${1}"/xxd -r - "${binaryPath}"
currentHex=`"${1}"/xxd -s "${cpuidx}" -ps -l 2 "${binaryPath}"`
}
else
{
echo "Error: ${cpuidx} value isn't \"0x0fa2\""
return 1
}
fi
done
}
fi
done
done
done
echo; echo "Finished decrypting apple-protected binaries and removing CPUID checks."
disptime
return 0
}
fi
}
removeCpuids "${SupportFiles}" "${1}"
exit 0
In case the link gets pulled here is the source for apb_decrypt with the key removed.
Its based on apb_encrypt created by
Amit Singh.
CODE
/* keys have been removed and need replacing, you will see where they go...
* apb_decrypt.c: Written for Mac OS X 10.5. Compile as follows:
*
* gcc -Wall -o apb_decrypt apb_decrypt.c -framework IOKit -lcrypto
*/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <copyfile.h>
#include <mach/mach.h>
#include <mach/machine.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include <openssl/aes.h>
#include <IOKit/IOKitLib.h>
#define APB_UNPROTECTED_HEADER_SIZE (3 * PAGE_SIZE)
#define APB_CRYPT_AES_KEY_SIZE (256)
#define APB_FAT_MAX_ARCH (5)
static char header_page[PAGE_SIZE];
static char data_page[PAGE_SIZE];
static char xcrypted_page[PAGE_SIZE];
static boolean_t apb_initialize(int, AES_KEY*, AES_KEY*);
static int apb_decrypt_page(const void*, void*);
static void AppleSMC_Read32_0(uint8_t*);
static void AppleSMC_Read32_1(uint8_t*);
typedef struct {
uint32_t key;
uint8_t __d0[22];
uint32_t datasize;
uint8_t __d1[10];
uint8_t cmd;
uint32_t __d2;
uint8_t data[32];
} AppleSMCBuffer_t;
static void
AppleSMC_Read32_0(uint8_t* data32)
{
(void)memcpy(data32, "1stThirtyTwoLettersOfKeyGoHere..", 32);
}
static void
AppleSMC_Read32_1(uint8_t* data32)
{
(void)memcpy(data32, "2ndThirtyTwoLettersOfKeyGoHere..", 32);
}
static boolean_t
apb_initialize(__unused int mode, AES_KEY* key1, AES_KEY* key2)
{
boolean_t result = FALSE;
uint8_t data32[32] = { 0 };
AppleSMC_Read32_0(data32);
AES_set_decrypt_key(data32, APB_CRYPT_AES_KEY_SIZE, key1);
AppleSMC_Read32_1(data32);
AES_set_decrypt_key(data32, APB_CRYPT_AES_KEY_SIZE, key2);
result = TRUE;
return result;
}
static int
apb_decrypt_page(const void* in, void* out)
{
static AES_KEY key1, key2;
static boolean_t initialized = FALSE;
if (initialized == FALSE) {
initialized = apb_initialize(AES_DECRYPT, &key1, &key2);
if (initialized == FALSE) {
return -1;
}
}
const unsigned char* _in = (const unsigned char*)in;
unsigned char* _out = (unsigned char*)out;
unsigned char apb_null_iv1[AES_BLOCK_SIZE] = { 0x0, };
unsigned char apb_null_iv2[AES_BLOCK_SIZE] = { 0x0, };
AES_cbc_encrypt(_in, _out, PAGE_SIZE / 2, &key1, apb_null_iv1, AES_DECRYPT);
_in += (PAGE_SIZE / 2);
_out += (PAGE_SIZE / 2);
AES_cbc_encrypt(_in, _out, PAGE_SIZE / 2, &key2, apb_null_iv2, AES_DECRYPT);
return 0;
}
int
main(int argc, char** argv)
{
int fd_in = -1;
int fd_out = -1;
if (argc != 3) {
fprintf(stderr, "usage: %s <infile> <outfile>\n", argv[0]);
exit(1);
}
fd_in = open(argv[1], O_RDONLY);
if (fd_in < 0) {
perror("open");
exit(1);
}
off_t base = (off_t)0;
off_t ebase_begin = (off_t)0;
off_t ebase_end = (off_t)0;
uint32_t n = 0;
int ret = 0;
ssize_t nbytes = pread(fd_in, header_page, PAGE_SIZE, (off_t)0);
if (nbytes != PAGE_SIZE) {
ret = -1;
goto out;
}
uint32_t magic = *(uint32_t*)header_page;
struct mach_header* mh = (struct mach_header*)0;
#ifdef __LITTLE_ENDIAN__
if (magic == FAT_CIGAM) {
struct fat_header* fh = (struct fat_header*)header_page;
uint32_t nfat_arch = ntohl(fh->nfat_arch);
if (nfat_arch > APB_FAT_MAX_ARCH) {
fprintf(stderr, "too many architectures in Universal binary\n");
ret = -1;
goto out;
}
struct fat_arch* fa = (struct fat_arch*)((char*)header_page +
sizeof(struct fat_header));
for (n = 0; n < nfat_arch; n++, fa++) {
if (ntohl(fa->cputype) == CPU_TYPE_X86) {
base = (off_t)ntohl(fa->offset);
nbytes = pread(fd_in, header_page, PAGE_SIZE, base);
if (nbytes != PAGE_SIZE) {
fprintf(stderr, "failed to read Universal binary\n");
ret = -1;
goto out;
}
mh = (struct mach_header*)header_page;
break;
}
}
} else if (magic == MH_MAGIC) {
mh = (struct mach_header*)header_page;
if (mh->cputype != CPU_TYPE_X86) {
fprintf(stderr, "this program supports only x86 architecture\n");
ret = -1;
goto out;
}
} else {
fprintf(stderr, "not an appropriate Mach-O file\n");
ret = -1;
goto out;
}
#else
#error This file can only be compiled on Intel.
#endif
struct segment_command* text = (struct segment_command*)0;
uint32_t ncmds = mh->ncmds;
struct load_command* lc =
(struct load_command*)((char*)mh + sizeof(struct mach_header));
for (n = 0; n < ncmds; n++) {
if (lc->cmd == LC_SEGMENT) {
struct segment_command* sc = (struct segment_command*)lc;
if (strcmp(sc->segname, SEG_TEXT) == 0) {
text = sc;
break;
}
}
lc = (struct load_command*)((char*)lc + lc->cmdsize);
}
if (!text) {
fprintf(stderr, "failed to find text segment\n");
ret = -1;
goto out;
}
if (text->flags ^ SG_PROTECTED_VERSION_1) {
fprintf(stderr, "not encrypted\n");
ret = -1;
goto out;
}
off_t archbase_begin = (off_t)(text->fileoff + APB_UNPROTECTED_HEADER_SIZE);
off_t archbase_end =
archbase_begin + (off_t)(text->filesize - APB_UNPROTECTED_HEADER_SIZE);
ebase_begin = base + archbase_begin;
ebase_end = base + archbase_end;
fd_out = open(argv[2], O_RDWR | O_CREAT | O_EXCL, 0755);
if (fd_out < 0) {
perror("open");
ret = -1;
goto out;
}
ret = fcopyfile(fd_in, fd_out, (copyfile_state_t)0, COPYFILE_ALL);
if (ret) {
perror("copyfile");
ret = -1;
goto out;
}
text->flags ^= SG_PROTECTED_VERSION_1;
nbytes = pwrite(fd_out, header_page, PAGE_SIZE, base);
if (nbytes != PAGE_SIZE) {
perror("pwrite");
ret = -1;
goto out;
}
off_t count = ebase_end - ebase_begin;
if (count % PAGE_SIZE) {
fprintf(stderr, "text segment not a multiple of page size\n");
ret = -1;
goto out;
}
while (count > 0) {
nbytes = pread(fd_in, data_page, PAGE_SIZE, ebase_begin);
if (nbytes != PAGE_SIZE) {
perror("pread");
ret = -1;
goto out;
}
ret = apb_decrypt_page(data_page, xcrypted_page);
if (ret) {
fprintf(stderr, "failed to decrypt page\n");
goto out;
}
nbytes = pwrite(fd_out, xcrypted_page, PAGE_SIZE, ebase_begin);
if (nbytes != PAGE_SIZE) {
perror("pwrite");
ret = -1;
goto out;
}
ebase_begin += (off_t)PAGE_SIZE;
count -= (off_t)PAGE_SIZE;
}
ret = 0;
out:
if (fd_in >= 0) {
close(fd_in);
}
if (fd_out >= 0) {
close(fd_out);
if (ret) {
unlink(argv[2]);
}
}
exit(ret);
}