Skip to content

Commit

Permalink
get/set image version
Browse files Browse the repository at this point in the history
  • Loading branch information
xerub committed Jul 21, 2017
1 parent c169fdd commit aeb21ee
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
28 changes: 26 additions & 2 deletions img4.c
Expand Up @@ -279,12 +279,14 @@ usage(const char *argv0)
printf(" -c <info> check signature with <info>\n");
printf(" -n print nonce\n");
printf(" -b print kbags\n");
printf(" -v print version\n");
printf("modifiers:\n");
printf(" -T <fourcc> set type <fourcc>\n");
printf(" -P[f|u] <file> apply patch from <file> (f=force, u=undo)\n");
printf(" -E <file> set extra from <file>\n");
printf(" -M <file> set ticket from <file>\n");
printf(" -N <nonce> set <nonce> if ticket is set/present\n");
printf(" -V <version> set <version>\n");
printf(" -D leave IMG4 decrypted\n");
printf(" -J convert lzfse to lzss\n");
printf("note: if no modifier is present and -o is specified, extract the bare image\n");
Expand All @@ -306,12 +308,14 @@ main(int argc, char **argv)
char *cinfo = NULL;
int get_nonce = 0;
int get_kbags = 0;
int get_version = 0;
const char *set_type = NULL;
const char *set_patch = NULL;
int pf = 0;
int pu = 0;
const char *set_extra = NULL;
const char *set_manifest = NULL;
const char *set_version = NULL;
int set_nonce = 0;
uint64_t nonce = 0;
int set_decrypt = 0;
Expand All @@ -337,6 +341,9 @@ main(int argc, char **argv)
case 'b':
get_kbags = 1;
continue;
case 'v':
get_version = 1;
continue;
case 'D':
set_decrypt = 1;
continue;
Expand Down Expand Up @@ -367,6 +374,8 @@ main(int argc, char **argv)
if (argc >= 2) { set_manifest = *++argv; argc--; continue; }
case 'N':
if (argc >= 2) { set_nonce = 1; nonce = strtoull(*++argv, NULL, 16); argc--; continue; }
case 'V':
if (argc >= 2) { set_version = *++argv; argc--; continue; }
/* fallthrough */
fprintf(stderr, "[e] argument to '%s' is missing\n", arg);
return -1;
Expand All @@ -387,7 +396,7 @@ main(int argc, char **argv)
return -1;
}

modify = set_type || set_patch || set_extra || set_manifest || set_nonce || set_decrypt || set_convert;
modify = set_type || set_patch || set_extra || set_manifest || set_nonce || set_decrypt || set_convert || set_version;

k = (unsigned char *)ik;
if (ik) {
Expand Down Expand Up @@ -420,7 +429,7 @@ main(int argc, char **argv)
fd->close(fd);
return -1;
}
if (!get_nonce && !get_kbags) {
if (!get_nonce && !get_kbags && !get_version) {
printf("%c%c%c%c\n", FOURCC(type));
}

Expand Down Expand Up @@ -485,6 +494,14 @@ main(int argc, char **argv)
printf("\n");
}
}
if (get_version) {
char *version;
size_t length;
rv = fd->ioctl(fd, IOCTL_IMG4_GET_VERSION, &version, &length);
if (rv == 0) {
printf("%.*s\n", (int)length, version);
}
}

// set stuff

Expand Down Expand Up @@ -537,6 +554,13 @@ main(int argc, char **argv)
}
rc |= rv;
}
if (set_version) {
rv = fd->ioctl(fd, IOCTL_IMG4_SET_VERSION, set_version, strlen(set_version));
if (rv) {
fprintf(stderr, "[e] cannot set version %s\n", set_version);
}
rc |= rv;
}
if (set_decrypt) {
rv = fd->ioctl(fd, IOCTL_ENC_SET_NOENC);
if (rv) {
Expand Down
6 changes: 4 additions & 2 deletions libvfs/vfs.h
Expand Up @@ -28,10 +28,12 @@ struct file_ops {
#define IOCTL_IMG4_GET_MANIFEST 62 /* (void **, size_t *) */
#define IOCTL_IMG4_SET_MANIFEST 63 /* (void *, size_t) */
#define IOCTL_IMG4_GET_NONCE 64 /* (unsigned long long *) */
#define IOCTL_IMG4_SET_NONCE 65 /* (unsigned long) */
#define IOCTL_IMG4_SET_NONCE 65 /* (unsigned long long) */
#define IOCTL_IMG4_GET_KEYBAG 66 /* (void **, size_t *) */
#define IOCTL_IMG4_GET_KEYBAG2 67 /* (unsigned char[48], unsigned char[48]) */
#define IOCTL_IMG4_EVAL_TRUST 68 /* (void *) */
#define IOCTL_IMG4_GET_VERSION 68 /* (void **, size_t *) */
#define IOCTL_IMG4_SET_VERSION 69 /* (void *, size_t) */
#define IOCTL_IMG4_EVAL_TRUST 70 /* (void *) */

typedef void (*free_t)(void *ptr);
typedef void *(*realloc_t)(void *ptr, size_t size);
Expand Down
21 changes: 21 additions & 0 deletions libvfs/vfs_img4.c
Expand Up @@ -1086,6 +1086,27 @@ img4_ioctl(FHANDLE fd, unsigned long req, ...)
rv = 0;
break;
}
case IOCTL_IMG4_GET_VERSION: {
void **dst = va_arg(ap, void **);
size_t *sz = va_arg(ap, size_t *);
*dst = ctx->version.data;
*sz = ctx->version.length;
rv = 0;
break;
}
case IOCTL_IMG4_SET_VERSION: if (fd->flags == O_RDONLY) break; else {
DERItem item;
void *old = ctx->version.data;
item.data = va_arg(ap, void *);
item.length = va_arg(ap, size_t);
rv = derdup(&ctx->version, &item);
if (rv) {
break;
}
free(old);
ctx->dirty = 1;
break;
}
case IOCTL_ENC_SET_NOENC: if (fd->flags == O_RDONLY) break; else {
FHANDLE pfd = ctx->pfd;
pfd->ioctl(pfd, req); /* may fail if enc is just a pass-through */
Expand Down

0 comments on commit aeb21ee

Please sign in to comment.