Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
divinebird committed Jan 26, 2016
0 parents commit 0296513
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 0 deletions.
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#CFLAGS=-O3 -Wall
CFLAGS=-g -ggdb -Wall
#LDLIBS=-l

all: pacextractor

version.h:
if [ ! -f version.h ]; then \
if [ -d .git ]; then \
echo '#define VERSION_STR "$(shell git describe --tags --abbrev=0)"' > version.h; \
else \
echo '#define VERSION_STR ""' > version.h; \
fi \
fi

pacextractor.o: version.h

clean:
rm -f pacextractor *.o version.h

.PHONY: clean all
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Extractor of SpreadTrum firmware files with extension pac

Extract all data that I may recognize in package.
143 changes: 143 additions & 0 deletions pacextractor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdint.h>

typedef struct {
int16_t someField[24];
int32_t someInt;
int16_t productName[256];
int16_t firmwareName[256];
int32_t partitionCount;
int32_t partitionsListStart;
int32_t someIntFields1[5];
int16_t productName2[50];
int16_t someIntFields2[6];
int16_t someIntFields3[2];
} PacHeader;

typedef struct {
uint32_t length;
int16_t partitionName[256];
int16_t fileName[512];
uint32_t partitionSize;
int32_t someFileds1[2];
uint32_t partitionAddrInPac;
int32_t someFileds2[3];
int32_t dataArray[];
} PartitionHeader;

void getString(int16_t* baseString, char* resString) {
if(*baseString == 0) {
*resString = 0;
return;
}
int length = 0;
do {
*resString = 0xFF & *baseString;
resString++;
baseString++;
if(++length > 256)
break;
} while(baseString > 0);
*resString = 0;
}

int main(int argc, char** argv) {
if(argc < 2) {
printf("command format:\n capextractor <firmware name>.pac");
exit(EXIT_FAILURE);
}

int fd = open(argv[1], O_RDONLY);
if (fd == -1) {
printf("file %s is not find", argv[1]);
exit(EXIT_FAILURE);
}

// fseek(fd, 0, SEEK_END);
// int firmwareSize = (fd);
// fseek(fd, 0, SEEK_SET);
struct stat st;
stat(argv[1], &st);
int firmwareSize = st.st_size;
if(firmwareSize < sizeof(PacHeader)) {
printf("file %s is not firmware", argv[1]);
exit(EXIT_FAILURE);
}

PacHeader pacHeader;
size_t rb =read(fd, &pacHeader, sizeof(PacHeader));
if(rb <= 0) {
printf("Error while parsing PAC header");
exit(EXIT_FAILURE);
}

char buffer[256];
char buffer1[256];
getString(pacHeader.firmwareName, buffer);
printf("Firmware name: %s\n", buffer);
uint32_t curPos = pacHeader.partitionsListStart;
PartitionHeader** partHeaders = malloc(sizeof(PartitionHeader**)*pacHeader.partitionCount);
int i;
for(i = 0; i < pacHeader.partitionCount; i++) {
lseek(fd, curPos, SEEK_SET);
uint32_t length;
rb =read(fd, &length, sizeof(uint32_t));
if(rb <= 0) {
printf("Partition header error");
exit(EXIT_FAILURE);
}
partHeaders[i] = malloc(length);
lseek(fd, curPos, SEEK_SET);
curPos += length;
rb =read(fd, partHeaders[i], length);
if(rb <= 0) {
printf("Partition header error");
exit(EXIT_FAILURE);
}
getString(partHeaders[i]->partitionName, buffer);
getString(partHeaders[i]->fileName, buffer1);
printf("Partition name: %s\n\twith file name: %s\n\twith size %u\n", buffer, buffer1, partHeaders[i]->partitionSize);
}

for(i = 0; i < pacHeader.partitionCount; i++) {
if(partHeaders[i]->partitionSize == 0) {
free(partHeaders[i]);
continue;
}
lseek(fd, partHeaders[i]->partitionAddrInPac, SEEK_SET);
getString(partHeaders[i]->fileName, buffer);
remove(buffer);
int fd_new = open(buffer, O_WRONLY | O_CREAT, 0666);
printf("Extract %s\n", buffer);
uint32_t dataSizeLeft = partHeaders[i]->partitionSize;
while(dataSizeLeft > 0) {
uint32_t copyLength = (dataSizeLeft > 256) ? 256 : dataSizeLeft;
dataSizeLeft -= copyLength;
rb =read(fd, buffer, copyLength);
if(rb != copyLength) {
printf("Partition image extraction error");
exit(EXIT_FAILURE);
}
rb = write(fd_new, buffer, copyLength);
if(rb != copyLength) {
printf("Partition image extraction error");
exit(EXIT_FAILURE);
}
printf("\r\t%02d%%", (uint64_t)100 - (uint64_t)100*dataSizeLeft/partHeaders[i]->partitionSize);
}
printf("\n");
close(fd_new);
free(partHeaders[i]);
}
free(partHeaders);
close(fd);

return EXIT_SUCCESS;
}

0 comments on commit 0296513

Please sign in to comment.