#include #include #include #include #include //Build with: gcc -o ropgadget_patternfinder ropgadget_patternfinder.c -lcrypto int load_bindata(char *arg, unsigned char **buf, unsigned int *size) { int i; unsigned int tmp=0; unsigned char *bufptr; FILE *f; struct stat filestat; bufptr = *buf; if(arg[0]!='@') { if(bufptr==NULL) { tmp = strlen(arg); if(tmp<2 || (tmp & 1)) { printf("The length of the input hex param is invalid.\n"); return 4; } *size = strlen(arg) / 2; *buf = (unsigned char*)malloc(*size); bufptr = *buf; if(bufptr==NULL) { printf("Failed to allocate memory for input buffer.\n"); return 1; } memset(bufptr, 0, *size); } for(i=0; i<*size; i++) { if(i>=strlen(arg))break; sscanf(&arg[i*2], "%02x", &tmp); bufptr[i] = (unsigned char)tmp; } } else { if(stat(&arg[1], &filestat)==-1) { printf("Failed to stat %s\n", &arg[1]); return 2; } f = fopen(&arg[1], "rb"); if(f==NULL) { printf("Failed to open %s\n", &arg[1]); return 2; } if(bufptr) { if(*size < filestat.st_size)*size = filestat.st_size; } else { *size = filestat.st_size; *buf = (unsigned char*)malloc(*size); bufptr = *buf; if(bufptr==NULL) { printf("Failed to allocate memory for input buffer.\n"); return 1; } memset(bufptr, 0, *size); } if(fread(bufptr, 1, *size, f) != *size) { printf("Failed to read file %s\n", &arg[1]); fclose(f); return 3; } fclose(f); } return 0; } int main(int argc, char **argv) { int argi; int ret; int patterntype = -1; unsigned int found, found2, findtarget=1; unsigned char *filebuf = NULL, *patterndata = NULL, *patternmask = NULL; unsigned char calchash[0x20]; size_t filebufsz=0, pos, i, hashblocksize=0; size_t patterndata_size=0, patternmask_size=0; unsigned int tmpsize=0; unsigned int stride = 4; unsigned int tmpval, tmpval2; struct stat filestat; FILE *fbin; if(argc<3) { printf("ropgadget_patternfinder by yellows8.\n"); printf("Locates the offset/address of the specified pattern in the input binary. This tool is mainly intended for locating ROP-gadgets, but it could be used for other purposes as well.\n"); printf(" below can be either hex with any byte-length(unless specified otherwise), or '@' followed by a file-path to load the data from."); printf("Usage:\n"); printf("ropgadget_patternfinder \n"); printf("Options:\n"); printf("--patterntype= Selects the pattern-type, which must be one of the following(this option is required): sha256 or datacmp. sha256: Hash every --patternsha256size bytes in the binary, for locating the target pattern. The input bindata(sha256 hash) size must be 0x20-bytes.\n"); printf("--patterndata= Pattern data to use during searching the binary, see --patterntype.\n"); printf("--patterndatamask= Mask data to use with pattern-type datacmp. The byte-size can be less than the size of patterndata as well. The data loaded from the filebuf is &= with this mask data.\n"); printf("--patternsha256size=0x See --patterntype.\n"); printf("--stride=0x In the search loop, this is the value that the pos is increased by at the end of each interation. By default this is 0x4.\n"); printf("--findtarget=0x Stop searching once this number of matches were found, by default this is 0x1. When this is 0x0, this will not stop until the end of the binary is reached.\n"); return 0; } ret = 0; for(argi=2; argi