Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
add_library(common abstractfile.c)
add_library(common abstractfile.c base64.c)

1 change: 1 addition & 0 deletions common/abstractfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ size_t memFileWrite(AbstractFile* file, const void* data, size_t len) {
}

if((info->offset + (size_t)len) > (*(info->bufferSize))) {
memset(((uint8_t*)(*(info->buffer))) + *(info->bufferSize), 0, (info->offset + (size_t)len) - *(info->bufferSize));
*(info->bufferSize) = info->offset + (size_t)len;
}

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion dmg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ link_directories(${ZLIB_LIBRARIES})

link_directories(${PROJECT_BINARY_DIR}/common ${PROJECT_BINARY_DIR}/hfs)

add_library(dmg adc.c base64.c checksum.c dmgfile.c dmglib.c filevault.c io.c partition.c resources.c udif.c)
add_library(dmg adc.c checksum.c dmgfile.c dmglib.c filevault.c io.c partition.c resources.c udif.c)

IF(OPENSSL_FOUND)
add_definitions(-DHAVE_CRYPT)
Expand Down
64 changes: 33 additions & 31 deletions dmg/checksum.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,17 @@ A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/

#define SHA1HANDSOFF * Copies data before messing with it.
#define SHA1HANDSOFF

void SHA1Transform(uint32_t state[5], const uint8_t buffer[64]);

#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))

/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */

/* FIXME: can we do this in an endian-proof way? */
#define blk0(i) ((endianness == IS_LITTLE_ENDIAN) ? (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF)) : block->l[i])

|(rol(block->l[i],8)&0x00FF00FF)) : block->l[i])
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))

Expand All @@ -188,30 +189,31 @@ A million repetitions of "a"
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);


/* Hash a single 512-bit block. This is the core of the algorithm. */

void SHA1Transform(unsigned long state[5], const unsigned char buffer[64])
void SHA1Transform(uint32_t state[5], const uint8_t buffer[64])
{
unsigned long a, b, c, d, e;
typedef union {
unsigned char c[64];
unsigned long l[16];
} CHAR64LONG16;
CHAR64LONG16* block;
uint32_t a, b, c, d, e;
typedef union {
uint8_t c[64];
uint32_t l[16];
} CHAR64LONG16;
CHAR64LONG16* block;

#ifdef SHA1HANDSOFF
static unsigned char workspace[64];
static uint8_t workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif

/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];

/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
Expand All @@ -233,19 +235,20 @@ static unsigned char workspace[64];
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);

/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;

/* Wipe variables */
a = b = c = d = e = 0;
}


/* SHA1Init - Initialize new context */

void SHA1Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
Expand All @@ -259,10 +262,9 @@ void SHA1Init(SHA1_CTX* context)


/* Run your data through this. */

void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
void SHA1Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
{
unsigned int i, j;
size_t i, j;

j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
Expand All @@ -271,7 +273,7 @@ unsigned int i, j;
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
SHA1Transform(context->state, data + i);
}
j = 0;
}
Expand All @@ -281,33 +283,33 @@ unsigned int i, j;


/* Add padding and return the message digest. */

void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
void SHA1Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX* context)
{
unsigned long i, j;
unsigned char finalcount[8];
uint32_t i;
uint8_t finalcount[8];

for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1Update(context, (unsigned char *)"\200", 1);
SHA1Update(context, (uint8_t *)"\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1Update(context, (unsigned char *)"\0", 1);
SHA1Update(context, (uint8_t *)"\0", 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
digest[i] = (uint8_t)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}

/* Wipe variables */
i = j = 0;
i = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(&finalcount, 0, 8);
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
memset(finalcount, 0, 8); /* SWR */

#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
SHA1Transform(context->state, context->buffer);
#endif
}

8 changes: 6 additions & 2 deletions dmg/dmg.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ int main(int argc, char* argv[]) {
TestByteOrder();

if(argc < 4) {
printf("usage: %s [extract|build|iso|dmg] <in> <out> (-k <key>) (partition)\n", argv[0]);
printf("usage: %s [extract|build|build2048|res|iso|dmg] <in> <out> (-k <key>) (partition)\n", argv[0]);
return 0;
}

Expand Down Expand Up @@ -72,7 +72,11 @@ int main(int argc, char* argv[]) {
}
extractDmg(in, out, partNum);
} else if(strcmp(argv[1], "build") == 0) {
buildDmg(in, out);
buildDmg(in, out, SECTOR_SIZE);
} else if(strcmp(argv[1], "build2048") == 0) {
buildDmg(in, out, 2048);
} else if(strcmp(argv[1], "res") == 0) {
outResources(in, out);
} else if(strcmp(argv[1], "iso") == 0) {
convertToISO(in, out);
} else if(strcmp(argv[1], "dmg") == 0) {
Expand Down
47 changes: 28 additions & 19 deletions dmg/dmglib.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ uint32_t calculateMasterChecksum(ResourceKey* resources) {
return result;
}

int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {
int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, unsigned int BlockSize) {
io_func* io;
Volume* volume;

Expand Down Expand Up @@ -129,15 +129,15 @@ int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {

printf("Creating and writing DDM and partition map...\n"); fflush(stdout);

DDM = createDriverDescriptorMap((volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE);
DDM = createDriverDescriptorMap((volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, BlockSize);

partitions = createApplePartitionMap((volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, HFSX_VOLUME_TYPE);
partitions = createApplePartitionMap((volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, HFSX_VOLUME_TYPE, BlockSize);

writeDriverDescriptorMap(abstractOut, DDM, &CRCProxy, (void*) (&dataForkToken), &resources);
int pNum = writeDriverDescriptorMap(-1, abstractOut, DDM, BlockSize, &CRCProxy, (void*) (&dataForkToken), &resources);
free(DDM);
writeApplePartitionMap(abstractOut, partitions, &CRCProxy, (void*) (&dataForkToken), &resources, &nsiz);
pNum = writeApplePartitionMap(pNum, abstractOut, partitions, BlockSize, &CRCProxy, (void*) (&dataForkToken), &resources, &nsiz);
free(partitions);
writeATAPI(abstractOut, &CRCProxy, (void*) (&dataForkToken), &resources, &nsiz);
pNum = writeATAPI(pNum, abstractOut, BlockSize, &CRCProxy, (void*) (&dataForkToken), &resources, &nsiz);

memset(&uncompressedToken, 0, sizeof(uncompressedToken));
SHA1Init(&(uncompressedToken.sha1));
Expand All @@ -146,15 +146,16 @@ int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {

abstractIn->seek(abstractIn, 0);
blkx = insertBLKX(abstractOut, abstractIn, USER_OFFSET, (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE,
2, CHECKSUM_CRC32, &BlockSHA1CRC, &uncompressedToken, &CRCProxy, &dataForkToken, volume);
pNum, CHECKSUM_CRC32, &BlockSHA1CRC, &uncompressedToken, &CRCProxy, &dataForkToken, volume, 1);

blkx->checksum.data[0] = uncompressedToken.crc;
printf("Inserting main blkx...\n"); fflush(stdout);

resources = insertData(resources, "blkx", 2, "Mac_OS_X (Apple_HFSX : 3)", (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);

char pName[100];
sprintf(pName, "Mac_OS_X (Apple_HFSX : %d)", pNum + 1);
resources = insertData(resources, "blkx", pNum, pName, (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
free(blkx);



printf("Inserting cSum data...\n"); fflush(stdout);

csum.version = 1;
Expand All @@ -180,21 +181,28 @@ int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {
if(nsiz == NULL) {
nsiz = myNSiz;
} else {
myNSiz->next = nsiz->next;
nsiz->next = myNSiz;
NSizResource* curNsiz = nsiz;
while(curNsiz->next != NULL)
{
curNsiz = curNsiz->next;
}
curNsiz->next = myNSiz;
}

pNum++;

printf("Writing free partition...\n"); fflush(stdout);

writeFreePartition(abstractOut, (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE, &resources);
pNum = writeFreePartition(pNum, abstractOut, USER_OFFSET + (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE,
(FREE_SIZE + (BlockSize / SECTOR_SIZE / 2)) / (BlockSize / SECTOR_SIZE) * (BlockSize / SECTOR_SIZE), &resources);

dataForkChecksum = dataForkToken.crc;

printf("Writing XML data...\n"); fflush(stdout);
curResource = resources;
while(curResource->next != NULL)
curResource = curResource->next;

curResource->next = writeNSiz(nsiz);
curResource = curResource->next;
releaseNSiz(nsiz);
Expand Down Expand Up @@ -240,7 +248,8 @@ int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {
printf("Master checksum: %x\n", koly.fUDIFMasterChecksum.data[0]); fflush(stdout);

koly.fUDIFImageVariant = kUDIFDeviceImageType;
koly.fUDIFSectorCount = EXTRA_SIZE + (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE;
koly.fUDIFSectorCount = (volumeHeader->totalBlocks * volumeHeader->blockSize)/SECTOR_SIZE
+ ((EXTRA_SIZE + (BlockSize / SECTOR_SIZE / 2)) / (BlockSize / SECTOR_SIZE) * (BlockSize / SECTOR_SIZE));
koly.reserved2 = 0;
koly.reserved3 = 0;
koly.reserved4 = 0;
Expand Down Expand Up @@ -311,7 +320,7 @@ int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut) {

if(DDM->sbSig == DRIVER_DESCRIPTOR_SIGNATURE) {
BlockSize = DDM->sbBlkSize;
writeDriverDescriptorMap(abstractOut, DDM, &CRCProxy, (void*) (&dataForkToken), &resources);
int pNum = writeDriverDescriptorMap(-1, abstractOut, DDM, BlockSize, &CRCProxy, (void*) (&dataForkToken), &resources);
free(DDM);

printf("Processing partition map...\n"); fflush(stdout);
Expand Down Expand Up @@ -342,7 +351,7 @@ int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut) {

abstractIn->seek(abstractIn, partitions[i].pmPyPartStart * BlockSize);
blkx = insertBLKX(abstractOut, abstractIn, partitions[i].pmPyPartStart, partitions[i].pmPartBlkCnt, i, CHECKSUM_CRC32,
&BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL);
&BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL, 1);

blkx->checksum.data[0] = uncompressedToken.crc;
resources = insertData(resources, "blkx", i, partitionName, (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
Expand Down Expand Up @@ -383,7 +392,7 @@ int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut) {

abstractIn->seek(abstractIn, 0);
blkx = insertBLKX(abstractOut, abstractIn, 0, fileLength/SECTOR_SIZE, ENTIRE_DEVICE_DESCRIPTOR, CHECKSUM_CRC32,
&BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL);
&BlockCRC, &uncompressedToken, &CRCProxy, &dataForkToken, NULL, 1);
blkx->checksum.data[0] = uncompressedToken.crc;
resources = insertData(resources, "blkx", 0, "whole disk (unknown partition : 0)", (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
free(blkx);
Expand Down
Loading