Skip to content

Instantly share code, notes, and snippets.

@vdudouyt
Last active January 1, 2016 23:19
Show Gist options
  • Save vdudouyt/8216131 to your computer and use it in GitHub Desktop.
Save vdudouyt/8216131 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int print_help_and_exit(const char *progname) {
fprintf(stderr, "Usage: %s <options> <filename> [<bytes>]\n"
"Options:\n"
" -b <base_addr> Use <base_addr> as base (will be substracted from <addr>)\n"
" -r <addr> Read first 16 bytes at <addr>\n"
" -w <addr> Write <bytes> at <addr>\n",
progname);
exit(-1);
}
void *xmalloc(int size) {
void *ret = malloc(size);
if(!ret) {
fprintf(stderr, "Couldn't malloc\n");
exit(-1);
}
return(ret);
}
FILE *xfopen(const char *filename, const char *mode, unsigned int addr) {
FILE *ret = fopen(filename, mode);
if(!ret)
perror("Couldn't open file");
fseek(ret, addr, SEEK_SET);
return(ret);
}
int act_read(const char *filename, unsigned int addr) {
unsigned char buf[16];
int i;
FILE *file = xfopen(filename, "rb", addr);
int bytes_read = fread(buf, 1, 16, file);
fclose(file);
for(i = 0; i < bytes_read; i++) {
printf("%02x ", buf[i]);
}
printf("\n");
}
int act_write(const char *filename, unsigned int addr, char *buf, int length) {
FILE *file = xfopen(filename, "rb+", addr);
fwrite(buf, 1, length, file);
fclose(file);
}
int main(int argc, char **argv) {
#define ACT_READ (1 << 0)
#define ACT_WRITE (1 << 1)
#define CHECK_USAGE(x) if(!(x)) { print_help_and_exit(argv[0]); }
unsigned int addr, base_addr = 0;
char c, action = 0;
int i;
// Parsing <options> with getopt
CHECK_USAGE(argc >= 1);
while ((c = getopt (argc, argv, "b:r:w:")) != -1) {
switch (c) {
case 'b':
sscanf(optarg, "%x", &base_addr);
break;
case 'r':
action |= ACT_READ;
sscanf(optarg, "%x", &addr);
break;
case 'w':
action |= ACT_WRITE;
sscanf(optarg, "%x", &addr);
break;
}
}
// Taking trailing <filename>
CHECK_USAGE(optind < argc);
char *filename = argv[optind];
optind++;
// Taking trailing <bytes>
int value;
char *bytes = NULL;
for(i = optind; i < argc; i++) {
if(bytes == NULL)
bytes = xmalloc(argc - optind);
sscanf(argv[i], "%02x", &value);
bytes[i-optind] = value;
}
// Executing an appropriate action
switch(action) {
case ACT_READ:
CHECK_USAGE(bytes == NULL);
act_read(filename, addr - base_addr);
break;
case ACT_WRITE:
CHECK_USAGE(bytes != NULL);
act_write(filename, addr - base_addr, bytes, argc - optind);
break;
default:
CHECK_USAGE(0);
}
free(bytes);
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment