Tinkered with valgrind, the makefiles, and enabled using filevault encrypted files as a backing source for dmg actions, so you can decrypt and extract at the same time

This commit is contained in:
planetbeing 2008-04-26 14:38:02 -04:00
Родитель b9fef5d9a8
Коммит 4b0f0db508
11 изменённых файлов: 507 добавлений и 240 удалений

19
Makefile Normal file
Просмотреть файл

@ -0,0 +1,19 @@
all: hfs dmg
dmg: dmg/dmg
hfs: hfs/hfsplus
dmg/dmg:
cd dmg; make
hfs/hfsplus:
cd hfs; make
clean:
cd dmg; make clean
cd hfs; make clean
dist-clean: clean
-cd dmg/zlib-1.2.3; make clean
-rm dmg/zlib-1.2.3/Makefile

Просмотреть файл

@ -1,15 +1,22 @@
DMGOBJS=dmg.o base64.o resources.o checksum.o udif.o partition.o io.o abstractfile.o zlib-1.2.3/libz.a
DMGOBJS=dmg.o base64.o resources.o checksum.o udif.o partition.o io.o abstractfile.o filevault.o zlib-1.2.3/libz.a
HFSOBJS=../hfs/volume.o ../hfs/btree.o ../hfs/extents.o ../hfs/rawfile.o ../hfs/catalog.o ../hfs/flatfile.o ../hfs/utility.o
CFLAGS=-D_FILE_OFFSET_BITS=64
CFLAGS=-D_FILE_OFFSET_BITS=64 -DHAVE_CRYPT
LIBRARIES=-lcrypto
all: dmg
dmg: $(DMGOBJS) $(HFSOBJS)
$(CC) $(CFLAGS) $(DMGOBJS) $(HFSOBJS) -o dmg
$(CC) $(CFLAGS) $(DMGOBJS) $(HFSOBJS) $(LIBRARIES) -o dmg
%.o: %.c dmg.h
%.o: %.c dmg.h filevault.h
$(CC) $(CFLAGS) -c $< -o $@
zlib-1.2.3/Makefile:
cd zlib-1.2.3; ./configure
zlib-1.2.3/libz.a: zlib-1.2.3/Makefile
cd zlib-1.2.3; make
clean:
rm *.o
rm dmg
-rm *.o
-rm dmg

Просмотреть файл

@ -165,3 +165,45 @@ void abstractFilePrint(AbstractFile* file, const char* format, ...) {
va_end(args);
ASSERT(file->write(file, buffer, length) == length, "fwrite");
}
int absFileRead(io_func* io, off_t location, size_t size, void *buffer) {
AbstractFile* file;
file = (AbstractFile*) io->data;
file->seek(file, location);
if(file->read(file, buffer, size) == size) {
return TRUE;
} else {
return FALSE;
}
}
int absFileWrite(io_func* io, off_t location, size_t size, void *buffer) {
AbstractFile* file;
file = (AbstractFile*) io->data;
file->seek(file, location);
if(file->write(file, buffer, size) == size) {
return TRUE;
} else {
return FALSE;
}
}
void closeAbsFile(io_func* io) {
AbstractFile* file;
file = (AbstractFile*) io->data;
file->close(file);
free(io);
}
io_func* IOFuncFromAbstractFile(AbstractFile* file) {
io_func* io;
io = (io_func*) malloc(sizeof(io_func));
io->data = file;
io->read = &absFileRead;
io->write = &absFileWrite;
io->close = &closeAbsFile;
return io;
}

118
dmg/dmg.c
Просмотреть файл

@ -4,6 +4,7 @@
#include <string.h>
#include "dmg.h"
#include "filevault.h"
char endianness;
@ -55,10 +56,7 @@ uint32_t calculateMasterChecksum(ResourceKey* resources) {
return result;
}
int buildDmg(const char* source, const char* dest) {
AbstractFile* abstractOut;
AbstractFile* abstractIn;
int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut) {
io_func* io;
Volume* volume;
@ -84,13 +82,11 @@ int buildDmg(const char* source, const char* dest) {
uint32_t plistSize;
uint32_t dataForkChecksum;
io = openFlatFileRO(source);
io = IOFuncFromAbstractFile(abstractIn);
volume = openVolume(io);
volumeHeader = volume->volumeHeader;
abstractIn = createAbstractFileFromFile(fopen(source, "rb"));
abstractOut = createAbstractFileFromFile(fopen(dest, "wb"));
if(volumeHeader->signature != HFSX_SIGNATURE) {
printf("Warning: ASR data only reverse engineered for case-sensitive HFS+ volumes\n");fflush(stdout);
}
@ -227,7 +223,6 @@ int buildDmg(const char* source, const char* dest) {
releaseResources(resources);
abstractOut->close(abstractOut);
abstractIn->close(abstractIn);
closeVolume(volume);
CLOSE(io);
@ -236,9 +231,7 @@ int buildDmg(const char* source, const char* dest) {
return TRUE;
}
int convertToDMG(const char* source, const char* dest) {
AbstractFile* abstractIn;
AbstractFile* abstractOut;
int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut) {
Partition* partitions;
DriverDescriptorRecord* DDM;
int i;
@ -276,9 +269,6 @@ int convertToDMG(const char* source, const char* dest) {
partitions = (Partition*) malloc(SECTOR_SIZE);
ASSERT(abstractIn = createAbstractFileFromFile(fopen(source, "rb")), "fopen");
ASSERT(abstractOut = createAbstractFileFromFile(fopen(dest, "wb")), "fopen");
printf("Processing DDM...\n"); fflush(stdout);
DDM = (DriverDescriptorRecord*) malloc(SECTOR_SIZE);
abstractIn->seek(abstractIn, 0);
@ -456,36 +446,18 @@ int convertToDMG(const char* source, const char* dest) {
return TRUE;
}
int convertToISO(const char* source, const char* dest) {
AbstractFile* abstractIn;
AbstractFile* abstractOut;
int convertToISO(AbstractFile* abstractIn, AbstractFile* abstractOut) {
off_t fileLength;
UDIFResourceFile resourceFile;
ResourceKey* resources;
ResourceData* blkx;
BLKXTable* blkxTable;
abstractIn = createAbstractFileFromFile(fopen(source, "rb"));
if(!abstractIn) {
fprintf(stderr, "Cannot open source file\n");
return FALSE;
}
fileLength = abstractIn->getLength(abstractIn);
abstractIn->seek(abstractIn, fileLength - sizeof(UDIFResourceFile));
readUDIFResourceFile(abstractIn, &resourceFile);
resources = readResources(abstractIn, &resourceFile);
abstractOut = createAbstractFileFromFile(fopen(dest, "wb"));
if(!abstractOut ) {
fprintf(stderr, "Cannot open target file\n");
releaseResources(resources);
abstractIn->close(abstractIn);
return FALSE;
}
blkx = (getResourceByKey(resources, "blkx"))->data;
printf("Writing out data..\n"); fflush(stdout);
@ -506,35 +478,17 @@ int convertToISO(const char* source, const char* dest) {
}
int extractDmg(const char* source, const char* dest, int partNum) {
AbstractFile* abstractIn;
AbstractFile* abstractOut;
int extractDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, int partNum) {
off_t fileLength;
UDIFResourceFile resourceFile;
ResourceKey* resources;
ResourceData* blkxData;
abstractIn = createAbstractFileFromFile(fopen(source, "rb"));
if(!abstractIn) {
fprintf(stderr, "Cannot open source file\n");
return FALSE;
}
fileLength = abstractIn->getLength(abstractIn);
abstractIn->seek(abstractIn, fileLength - sizeof(UDIFResourceFile));
readUDIFResourceFile(abstractIn, &resourceFile);
resources = readResources(abstractIn, &resourceFile);
abstractOut = createAbstractFileFromFile(fopen(dest, "wb"));
if(!abstractOut) {
fprintf(stderr, "Cannot open target file\n");
releaseResources(resources);
abstractIn->close(abstractIn);
return FALSE;
}
printf("Writing out data..\n"); fflush(stdout);
/* reasonable assumption that 2 is the main partition, given that that's usually the case in SPUD layouts */
@ -552,29 +506,69 @@ int extractDmg(const char* source, const char* dest, int partNum) {
return TRUE;
}
int buildInOut(const char* source, const char* dest, AbstractFile** in, AbstractFile** out) {
*in = createAbstractFileFromFile(fopen(source, "rb"));
if(!(*in)) {
printf("cannot open source: %s\n", source);
return FALSE;
}
*out = createAbstractFileFromFile(fopen(dest, "wb"));
if(!(*out)) {
(*in)->close(*in);
printf("cannot open destination: %s\n", dest);
return FALSE;
}
return TRUE;
}
int main(int argc, char* argv[]) {
int partNum;
AbstractFile* in;
AbstractFile* out;
int index;
int hasKey;
TestByteOrder();
if(argc < 4) {
printf("usage: %s [extract <dmg> <img> (partition)|build <img> <dmg>]\n", argv[0]);
printf("usage: %s [extract|build|iso|dmg] <in> <out> (-k <key>) (partition)\n", argv[0]);
return 0;
}
if(!buildInOut(argv[2], argv[3], &in, &out)) {
return FALSE;
}
hasKey = FALSE;
if(argc > 5) {
if(strcmp(argv[4], "-k") == 0) {
in = createAbstractFileFromFileVault(in, argv[5]);
hasKey = TRUE;
}
}
if(strcmp(argv[1], "extract") == 0) {
partNum = 2;
if(argc > 4) {
sscanf(argv[4], "%d", &partNum);
if(hasKey) {
if(argc > 6) {
sscanf(argv[6], "%d", &partNum);
}
} else {
if(argc > 4) {
sscanf(argv[4], "%d", &partNum);
}
}
extractDmg(argv[2], argv[3], partNum);
extractDmg(in, out, partNum);
} else if(strcmp(argv[1], "build") == 0) {
buildDmg(argv[2], argv[3]);
buildDmg(in, out);
} else if(strcmp(argv[1], "iso") == 0) {
convertToISO(argv[2], argv[3]);
convertToISO(in, out);
} else if(strcmp(argv[1], "dmg") == 0) {
convertToDMG(argv[2], argv[3]);
convertToDMG(in, out);
}
return 0;

Просмотреть файл

@ -1,3 +1,6 @@
#ifndef DMG_H
#define DMG_H
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
@ -349,6 +352,7 @@ AbstractFile* createAbstractFileFromFile(FILE* file);
AbstractFile* createAbstractFileFromDummy();
AbstractFile* createAbstractFileFromMemory(void* buffer, size_t size);
void abstractFilePrint(AbstractFile* file, const char* format, ...);
io_func* IOFuncFromAbstractFile(AbstractFile* file);
void extractBLKX(AbstractFile* in, AbstractFile* out, BLKXTable* blkx);
BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorNumber, uint32_t numSectors, uint32_t blocksDescriptor,
@ -356,8 +360,9 @@ BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorN
void* compressedChkToken, Volume* volume);
int extractDmg(const char* source, const char* dest, int partNum);
int buildDmg(const char* source, const char* dest);
int convertToISO(const char* source, const char* dest);
int convertToDMG(const char* source, const char* dest);
int extractDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, int partNum);
int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut);
int convertToISO(AbstractFile* abstractIn, AbstractFile* abstractOut);
int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut);
#endif

245
dmg/filevault.c Normal file
Просмотреть файл

@ -0,0 +1,245 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dmg.h"
#include "filevault.h"
#ifdef HAVE_CRYPT
#include <openssl/hmac.h>
#include <openssl/aes.h>
#define CHUNKNO(oft) ((uint32_t)((oft)/FILEVAULT_CHUNK_SIZE))
#define CHUNKOFFSET(oft) ((size_t)((oft) - ((off_t)(CHUNKNO(oft)) * (off_t)FILEVAULT_CHUNK_SIZE)))
#define CHUNKBEGIN(oft) C_OFFSET(CHUNKNO(oft))
static void flipFileVaultV2Header(FileVaultV2Header* header) {
FLIPENDIAN(header->signature);
FLIPENDIAN(header->version);
FLIPENDIAN(header->encIVSize);
FLIPENDIAN(header->unk1);
FLIPENDIAN(header->unk2);
FLIPENDIAN(header->unk3);
FLIPENDIAN(header->unk4);
FLIPENDIAN(header->unk5);
FLIPENDIAN(header->unk5);
FLIPENDIAN(header->blockSize);
FLIPENDIAN(header->dataSize);
FLIPENDIAN(header->dataOffset);
FLIPENDIAN(header->kdfAlgorithm);
FLIPENDIAN(header->kdfPRNGAlgorithm);
FLIPENDIAN(header->kdfIterationCount);
FLIPENDIAN(header->kdfSaltLen);
FLIPENDIAN(header->blobEncIVSize);
FLIPENDIAN(header->blobEncKeyBits);
FLIPENDIAN(header->blobEncAlgorithm);
FLIPENDIAN(header->blobEncPadding);
FLIPENDIAN(header->blobEncMode);
FLIPENDIAN(header->encryptedKeyblobSize);
}
static void writeChunk(FileVaultInfo* info) {
unsigned char buffer[FILEVAULT_CHUNK_SIZE];
unsigned char buffer2[FILEVAULT_CHUNK_SIZE];
unsigned char msgDigest[FILEVAULT_MSGDGST_LENGTH];
uint32_t msgDigestLen;
uint32_t myChunk;
myChunk = info->curChunk;
FLIPENDIAN(myChunk);
HMAC_Init_ex(&(info->hmacCTX), NULL, 0, NULL, NULL);
HMAC_Update(&(info->hmacCTX), (void *) &myChunk, sizeof(uint32_t));
HMAC_Final(&(info->hmacCTX), msgDigest, &msgDigestLen);
AES_cbc_encrypt(info->chunk, buffer, FILEVAULT_CHUNK_SIZE, &(info->aesEncKey), msgDigest, AES_ENCRYPT);
info->file->seek(info->file, (info->curChunk * FILEVAULT_CHUNK_SIZE) + info->header.v2.dataOffset);
info->file->read(info->file, buffer2, FILEVAULT_CHUNK_SIZE);
info->file->seek(info->file, (info->curChunk * FILEVAULT_CHUNK_SIZE) + info->header.v2.dataOffset);
info->file->write(info->file, buffer, FILEVAULT_CHUNK_SIZE);
info->dirty = FALSE;
}
static void cacheChunk(FileVaultInfo* info, uint32_t chunk) {
unsigned char buffer[FILEVAULT_CHUNK_SIZE];
unsigned char buffer2[FILEVAULT_CHUNK_SIZE];
unsigned char msgDigest[FILEVAULT_MSGDGST_LENGTH];
unsigned char msgDigest2[FILEVAULT_MSGDGST_LENGTH];
uint32_t msgDigestLen;
if(chunk == info->curChunk) {
return;
}
if(info->dirty) {
writeChunk(info);
}
info->file->seek(info->file, chunk * FILEVAULT_CHUNK_SIZE + info->header.v2.dataOffset);
info->file->read(info->file, buffer, FILEVAULT_CHUNK_SIZE);
info->curChunk = chunk;
FLIPENDIAN(chunk);
HMAC_Init_ex(&(info->hmacCTX), NULL, 0, NULL, NULL);
HMAC_Update(&(info->hmacCTX), (void *) &chunk, sizeof(uint32_t));
HMAC_Final(&(info->hmacCTX), msgDigest, &msgDigestLen);
AES_cbc_encrypt(buffer, info->chunk, FILEVAULT_CHUNK_SIZE, &(info->aesKey), msgDigest, AES_DECRYPT);
}
size_t fvRead(AbstractFile* file, void* data, size_t len) {
size_t lengthInCurrentChunk;
FileVaultInfo* info;
size_t toRead;
info = (FileVaultInfo*) (file->data);
if((CHUNKOFFSET(info->offset) + len) > FILEVAULT_CHUNK_SIZE) {
toRead = FILEVAULT_CHUNK_SIZE - CHUNKOFFSET(info->offset);
memcpy(data, (void *)((uint64_t)(&(info->chunk)) + (uint64_t)CHUNKOFFSET(info->offset)), toRead);
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset));
return toRead + fvRead(file, (void *)((uint64_t)data + (uint64_t)toRead), len - toRead);
} else {
toRead = len;
memcpy(data, (void *)((uint64_t)(&(info->chunk)) + (uint64_t)CHUNKOFFSET(info->offset)), toRead);
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset));
return toRead;
}
}
size_t fvWrite(AbstractFile* file, const void* data, size_t len) {
size_t lengthInCurrentChunk;
FileVaultInfo* info;
size_t toRead;
int i;
info = (FileVaultInfo*) (file->data);
if((CHUNKOFFSET(info->offset) + len) > FILEVAULT_CHUNK_SIZE) {
toRead = FILEVAULT_CHUNK_SIZE - CHUNKOFFSET(info->offset);
for(i = 0; i < toRead; i++) {
ASSERT(*((char*)((uint64_t)(&(info->chunk)) + (uint64_t)CHUNKOFFSET(info->offset) + i)) == ((char*)data)[i], "blah");
}
memcpy((void *)((uint64_t)(&(info->chunk)) + (uint64_t)CHUNKOFFSET(info->offset)), data, toRead);
info->dirty = TRUE;
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset));
return toRead + fvWrite(file, (void *)((uint64_t)data + (uint64_t)toRead), len - toRead);
} else {
toRead = len;
for(i = 0; i < toRead; i++) {
ASSERT(*((char*)((uint64_t)(&(info->chunk)) + (uint64_t)CHUNKOFFSET(info->offset) + i)) == ((char*)data)[i], "blah");
}
memcpy((void *)((uint64_t)(&(info->chunk)) + (uint64_t)CHUNKOFFSET(info->offset)), data, toRead);
info->dirty = TRUE;
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset));
return toRead;
}
}
int fvSeek(AbstractFile* file, off_t offset) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
info->offset = offset;
cacheChunk(info, CHUNKNO(offset));
return 0;
}
off_t fvTell(AbstractFile* file) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
return info->offset;
}
off_t fvGetLength(AbstractFile* file) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
return info->header.v2.dataSize;
}
void fvClose(AbstractFile* file) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
/* force a flush */
if(info->curChunk == 0) {
cacheChunk(info, 1);
} else {
cacheChunk(info, 0);
}
HMAC_CTX_cleanup(&(info->hmacCTX));
info->file->close(info->file);
free(info);
free(file);
}
AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key) {
FileVaultInfo* info;
AbstractFile* toReturn;
uint64_t signature;
uint8_t aesKey[16];
uint8_t hmacKey[20];
int i;
file->seek(file, 0);
file->read(file, &signature, sizeof(uint64_t));
FLIPENDIAN(signature);
if(signature != FILEVAULT_V2_SIGNATURE) {
/* no FileVault v1 handling yet */
return NULL;
}
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
info = (FileVaultInfo*) malloc(sizeof(FileVaultInfo));
file->seek(file, 0);
file->read(file, &(info->header.v2), sizeof(FileVaultV2Header));
flipFileVaultV2Header(&(info->header.v2));
for(i = 0; i < 16; i++) {
sscanf(&(key[i * 2]), "%02hhx", &(aesKey[i]));
}
for(i = 0; i < 20; i++) {
sscanf(&(key[(16 * 2) + i * 2]), "%02hhx", &(hmacKey[i]));
}
HMAC_CTX_init(&(info->hmacCTX));
HMAC_Init_ex(&(info->hmacCTX), hmacKey, sizeof(hmacKey), EVP_sha1(), NULL);
AES_set_decrypt_key(aesKey, FILEVAULT_CIPHER_KEY_LENGTH * 8, &(info->aesKey));
AES_set_encrypt_key(aesKey, FILEVAULT_CIPHER_KEY_LENGTH * 8, &(info->aesEncKey));
info->offset = 0;
info->file = file;
info->dirty = FALSE;
info->curChunk = 1; /* just to set it to a value not 0 */
cacheChunk(info, 0);
toReturn->data = info;
toReturn->read = fvRead;
toReturn->write = fvWrite;
toReturn->seek = fvSeek;
toReturn->tell = fvTell;
toReturn->getLength = fvGetLength;
toReturn->close = fvClose;
return toReturn;
}
#else
AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key) {
return NULL;
}
#endif

92
dmg/filevault.h Normal file
Просмотреть файл

@ -0,0 +1,92 @@
#ifndef FILEVAULT_H
#define FILEVAULT_H
#include <stdint.h>
#include "dmg.h"
#ifdef HAVE_CRYPT
#include <openssl/hmac.h>
#include <openssl/aes.h>
#define FILEVAULT_CIPHER_KEY_LENGTH 16
#define FILEVAULT_CIPHER_BLOCKSIZE 16
#define FILEVAULT_CHUNK_SIZE 4096
#define FILEVAULT_PBKDF2_ITER_COUNT 1000
#define FILEVAULT_MSGDGST_LENGTH 20
/*
* Information about the FileVault format was yoinked from vfdecrypt, which was written by Ralf-Philipp Weinmann <ralf@coderpunks.org>,
* Jacob Appelbaum <jacob@appelbaum.net>, and Christian Fromme <kaner@strace.org>
*/
#define FILEVAULT_V2_SIGNATURE 0x656e637263647361
typedef struct FileVaultV1Header {
uint8_t padding1[48];
uint32_t kdfIterationCount;
uint32_t kdfSaltLen;
uint8_t kdfSalt[48];
uint8_t unwrapIV[0x20];
uint32_t wrappedAESKeyLen;
uint8_t wrappedAESKey[296];
uint32_t wrappedHMACSHA1KeyLen;
uint8_t wrappedHMACSHA1Key[300];
uint32_t integrityKeyLen;
uint8_t integrityKey[48];
uint8_t padding2[484];
} __attribute__((__packed__)) FileVaultV1Header;
typedef struct FileVaultV2Header {
uint64_t signature;
uint32_t version;
uint32_t encIVSize;
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t unk4;
uint32_t unk5;
UDIFID uuid;
uint32_t blockSize;
uint64_t dataSize;
uint64_t dataOffset;
uint8_t padding[0x260];
uint32_t kdfAlgorithm;
uint32_t kdfPRNGAlgorithm;
uint32_t kdfIterationCount;
uint32_t kdfSaltLen;
uint8_t kdfSalt[0x20];
uint32_t blobEncIVSize;
uint8_t blobEncIV[0x20];
uint32_t blobEncKeyBits;
uint32_t blobEncAlgorithm;
uint32_t blobEncPadding;
uint32_t blobEncMode;
uint32_t encryptedKeyblobSize;
uint8_t encryptedKeyblob[0x30];
} __attribute__((__packed__)) FileVaultV2Header;
typedef struct FileVaultInfo {
union {
FileVaultV1Header v1;
FileVaultV2Header v2;
} header;
AbstractFile* file;
HMAC_CTX hmacCTX;
AES_KEY aesKey;
AES_KEY aesEncKey;
off_t offset;
uint32_t curChunk;
unsigned char chunk[FILEVAULT_CHUNK_SIZE];
char dirty;
} FileVaultInfo;
#endif
AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key);
#endif

Просмотреть файл

@ -1,154 +0,0 @@
# Makefile for zlib
# Copyright (C) 1995-2005 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile and test, type:
# ./configure; make test
# The call of configure is optional if you don't have special requirements
# If you wish to build zlib as a shared library, use: ./configure -s
# To use the asm code, type:
# cp contrib/asm?86/match.S ./match.S
# make LOC=-DASMV OBJA=match.o
# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
# make install
# To install in $HOME instead of /usr/local, use:
# make install prefix=$HOME
CC=gcc
CFLAGS=-O3 -DUSE_MMAP
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-g -DDEBUG
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
# -Wstrict-prototypes -Wmissing-prototypes
LDFLAGS=-L. libz.a
LDSHARED=gcc
CPP=gcc -E
LIBS=libz.a
SHAREDLIB=libz.so
SHAREDLIBV=libz.so.1.2.3
SHAREDLIBM=libz.so.1
AR=ar rc
RANLIB=ranlib
TAR=tar
SHELL=/bin/sh
EXE=
prefix =/usr/local
exec_prefix =${prefix}
libdir =${exec_prefix}/lib
includedir =${prefix}/include
mandir =${prefix}/share/man
man3dir = ${mandir}/man3
OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
zutil.o inflate.o infback.o inftrees.o inffast.o
OBJA =
# to use the asm code: make OBJA=match.o
TEST_OBJS = example.o minigzip.o
all: example$(EXE) minigzip$(EXE)
check: test
test: all
@LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
echo hello world | ./minigzip | ./minigzip -d || \
echo ' *** minigzip test FAILED ***' ; \
if ./example; then \
echo ' *** zlib test OK ***'; \
else \
echo ' *** zlib test FAILED ***'; \
fi
libz.a: $(OBJS) $(OBJA)
$(AR) $@ $(OBJS) $(OBJA)
-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
match.o: match.S
$(CPP) match.S > _match.s
$(CC) -c _match.s
mv _match.o match.o
rm -f _match.s
$(SHAREDLIBV): $(OBJS)
$(LDSHARED) -o $@ $(OBJS)
rm -f $(SHAREDLIB) $(SHAREDLIBM)
ln -s $@ $(SHAREDLIB)
ln -s $@ $(SHAREDLIBM)
example$(EXE): example.o $(LIBS)
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
minigzip$(EXE): minigzip.o $(LIBS)
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
install: $(LIBS)
-@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi
-@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi
-@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi
-@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi
cp zlib.h zconf.h $(includedir)
chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
cp $(LIBS) $(libdir)
cd $(libdir); chmod 755 $(LIBS)
-@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
cd $(libdir); if test -f $(SHAREDLIBV); then \
rm -f $(SHAREDLIB) $(SHAREDLIBM); \
ln -s $(SHAREDLIBV) $(SHAREDLIB); \
ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
(ldconfig || true) >/dev/null 2>&1; \
fi
cp zlib.3 $(man3dir)
chmod 644 $(man3dir)/zlib.3
# The ranlib in install is needed on NeXTSTEP which checks file times
# ldconfig is for Linux
uninstall:
cd $(includedir); \
cd $(libdir); rm -f libz.a; \
if test -f $(SHAREDLIBV); then \
rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
fi
cd $(man3dir); rm -f zlib.3
mostlyclean: clean
clean:
rm -f *.o *~ example$(EXE) minigzip$(EXE) \
libz.* foo.gz so_locations \
_match.s maketree contrib/infback9/*.o
maintainer-clean: distclean
distclean: clean
cp -p Makefile.in Makefile
cp -p zconf.in.h zconf.h
rm -f .DS_Store
tags:
etags *.[ch]
depend:
makedepend -- $(CFLAGS) -- *.[ch]
# DO NOT DELETE THIS LINE -- make depend depends on it.
adler32.o: zlib.h zconf.h
compress.o: zlib.h zconf.h
crc32.o: crc32.h zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
example.o: zlib.h zconf.h
gzio.o: zutil.h zlib.h zconf.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h

Просмотреть файл

@ -10,6 +10,6 @@ hfsplus: $(HFSPLUSOBJS)
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm *.o
rm hfsplus
-rm *.o
-rm hfsplus

Просмотреть файл

@ -11,6 +11,7 @@
#define FALSE 0
#define FLIPENDIAN(x) flipEndian((unsigned char *)(&(x)), sizeof(x))
#define FLIPENDIANLE(x) flipEndianLE((unsigned char *)(&(x)), sizeof(x))
#define IS_BIG_ENDIAN 0
#define IS_LITTLE_ENDIAN 1
@ -38,4 +39,32 @@ static inline void flipEndian(unsigned char* x, int length) {
}
}
static inline void flipEndianLE(unsigned char* x, int length) {
int i;
unsigned char tmp;
if(endianness == IS_LITTLE_ENDIAN) {
return;
} else {
for(i = 0; i < (length / 2); i++) {
tmp = x[i];
x[i] = x[length - i - 1];
x[length - i - 1] = tmp;
}
}
}
struct io_func_struct;
typedef int (*readFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef int (*writeFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef void (*closeFunc)(struct io_func_struct* io);
typedef struct io_func_struct {
void* data;
readFunc read;
writeFunc write;
closeFunc close;
} io_func;
#endif

Просмотреть файл

@ -11,8 +11,6 @@
#define WRITE_KEY(a, b, c, d) ((*((a)->keyWrite))(b, c, d))
#define READ_DATA(a, b, c) ((*((a)->dataRead))(b, c))
struct io_func_struct;
struct BTKey {
uint16_t keyLength;
unsigned char data[0];
@ -20,9 +18,6 @@ struct BTKey {
typedef struct BTKey BTKey;
typedef int (*readFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef int (*writeFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef void (*closeFunc)(struct io_func_struct* io);
typedef BTKey* (*dataReadFunc)(off_t offset, struct io_func_struct* io);
typedef void (*keyPrintFunc)(BTKey* toPrint);
typedef int (*keyWriteFunc)(off_t offset, BTKey* toWrite, struct io_func_struct* io);
@ -383,13 +378,6 @@ struct CatalogRecordList {
};
typedef struct CatalogRecordList CatalogRecordList;
typedef struct io_func_struct {
void* data;
readFunc read;
writeFunc write;
closeFunc close;
} io_func;
struct Extent {
uint32_t startBlock;
uint32_t blockCount;