size_t binhack_calc_size(const char *binhack_str) { size_t size = 0; const char *c = binhack_str; const char *fs = NULL; // function start if(!binhack_str) { return 0; } while(*c) { if(!fs && is_valid_hex(*c) && is_valid_hex(*(c+1)) ) { size++; c++; } else if(*c == '[' || *c == '<') { if(fs) { log_printf("ERROR: Nested function pointers near %s!\n", c); return 0; } fs = c + 1; } else if(fs && (*c == ']' || *c == '>')) { size += sizeof(void*); fs = NULL; } c++; } if(fs) { log_printf("ERROR: Function name '%s' not terminated...\n", fs); size = 0; } return size; }
int binhack_render(BYTE *binhack_buf, size_t target_addr, const char *binhack_str) { const char *c = binhack_str; const char *fs = NULL; // function start size_t written = 0; int func_rel = 0; // Relative function pointer flag char conv[3]; int ret = 0; if(!binhack_buf || !binhack_str) { return -1; } conv[2] = 0; while(*c) { if(!fs && is_valid_hex(*c) && is_valid_hex(*(c+1)) ) { memcpy(conv, c, 2); *binhack_buf = (char)strtol(conv, NULL, 16); binhack_buf++; c++; written++; } else if(*c == '[' || *c == '<') { if(fs) { log_printf("ERROR: Nested function pointers near %s!\n", c); return 0; } func_rel = (*c == '['); fs = c + 1; } else if(fs && (*c == ']' || *c == '>')) { VLA(char, function, (c - fs) + 1); size_t fp = 0; strncpy(function, fs, c - fs); function[c - fs] = 0; fp = (size_t)func_get(function); if(fp) { if(func_rel) { fp -= target_addr + written + sizeof(void*); } memcpy(binhack_buf, &fp, sizeof(void*)); binhack_buf += sizeof(void*); written += sizeof(void*); } else { log_printf("ERROR: No pointer for function '%s'...\n", function); ret = 2; } fs = NULL; VLA_FREE(function); if(ret) { break; } } c++; }
// Returns false only if parsing should be aborted. bool consume_value(value_t &val, const char** str) { assert(str); const char *c = *str; // Double / float if(*c == '+' || *c == '-') { if(!lc_neutral) { lc_neutral = _create_locale(LC_NUMERIC, "C"); } char *endptr; errno = 0; double result = _strtod_l(*str, &endptr, lc_neutral); if(errno == ERANGE && (result == HUGE_VAL || result == -HUGE_VAL)) { auto val_len = (endptr - *str); log_printf( "ERROR: Floating point constant \"%.*s\" out of range!\n", val_len, str ); return false; } else if(endptr == *str) { // Not actually a floating-point number, keep going though *str += 1; return true; } if(*endptr == 'f') { val.type = VT_FLOAT; val.f = (float)result; endptr++; } else { val.type = VT_DOUBLE; val.d = result; } if(*endptr != ' ' && *endptr != '\0') { val.type = VT_NONE; *str += 1; } else { *str = endptr; } } // Byte else if(is_valid_hex(c[0]) && is_valid_hex(c[1])) { char conv[3]; conv[2] = 0; memcpy(conv, *str, 2); val.type = VT_BYTE; val.b = (unsigned char)strtol(conv, nullptr, 16); *str += 2; } // Nothing, keep going else { *str += 1; } return true; }
int htoi(const char s[]) { unsigned int res = 0; int c, i = 0; if (is_valid_hex(s) == -1) { return -1; } //skip 0x prefix i = 2; while(s[i] != '\0') { c = lower(s[i]); res = res * 16; if (c >= '0' && c <= '9') { res = res + (c - '0'); } else { res = res + hex_to_int(c); } i++; } return res; }
// set color using a color hex code as a string PPM_Color::PPM_Color(const std::string &s): color_{0} { if (is_valid_hex(s)) color_ = stoul(s, nullptr, 16); else std::cerr << "warning: invalid color code, color set to black\n"; }