Pastebin
API
tools
faq
paste
Login
Sign up
Please fix the following errors:
New Paste
Syntax Highlighting
// // main.m // extracthalotagdefs // // Created by silent on 8/3/18. // Copyright © 2018 haloserver. All rights reserved. // #import <stdio.h> #import <stdlib.h> #import <string.h> #import <stdbool.h> const uint8_t negone[] = { 0xFF, 0xFF, 0xFF, 0xFF }; const char* hex = "0123456789abcdef"; static uint32_t min_filesizes[83] = {0}; static uint32_t max_filesizes[83] = {0}; // used to store file data struct file_data { size_t length; //size_t* offset; // dynamic number indicating offset from bytes, for "pointer math" during sequential parsing of bytes void* bytes; }; #define MEMREGION 0x400000 // subtract this from all pointer values to obtain file data offset #define GUERILLA_DEFS_INDEX 0x5b8d88 // the actual file data offset start for mode tag enum datatypes { datatype_string = 0x00, datatype_char_integer = 0x01, datatype_short_integer = 0x02, datatype_long_integer = 0x03, datatype_angle = 0x04, datatype_tag = 0x05, datatype_enum = 0x06, datatype_long_flags = 0x07, datatype_word_flags = 0x08, datatype_byte_flags = 0x09, datatype_point_2d = 0x0A, datatype_rectangle_2d = 0x0B, datatype_rgb_color = 0x0C, datatype_argb_color = 0x0D, datatype_real = 0x0E, datatype_real_fraction = 0x0F, datatype_real_point_2d = 0x10, datatype_real_point_3d = 0x11, datatype_real_vector_2d = 0x12, datatype_real_vector_3d = 0x13, datatype_real_quaternion = 0x14, datatype_real_euler_angles_2d = 0x15, datatype_real_euler_angles_3d = 0x16, datatype_real_plane_2d = 0x17, datatype_real_plane_3d = 0x18, datatype_real_rgb_color = 0x19, datatype_real_argb_color = 0x1A, datatype_real_hsv_color = 0x1B, datatype_real_ahsv_color = 0x1C, datatype_short_integer_bounds = 0x1D, datatype_angle_bounds = 0x1E, datatype_real_bounds = 0x1F, datatype_fraction_bounds = 0x20, datatype_tag_reference = 0x21, datatype_block = 0x22, datatype_short_block_index = 0x23, datatype_long_block_index = 0x24, datatype_data = 0x25, datatype_array_start = 0x26, datatype_array_end = 0x27, datatype_pad = 0x28, datatype_skip = 0x29, datatype_explanation = 0x2A, datatype_custom = 0x2B, datatype_terminator_X = 0x2C }; struct entry_number_field { enum datatypes type; char* name; uint8_t pad[4]; }; struct entry_struct_field { enum datatypes type; char* name; void* definition; }; struct entry_pad_field { enum datatypes type; uint8_t pad[4]; uint32_t size; }; struct entry_dependency_info { uint32_t usage_flags; char class[4]; uint8_t pad_2[4]; }; struct entry_dependency_field { enum datatypes type; char* name; struct entry_dependency_info definition; // pointer }; struct entry_flags_info { uint32_t count; char* (*names)[]; // pointer to array of pointers }; struct entry_flags_field { enum datatypes type; char* name; struct entry_flags_info info; // a pointer }; struct entry_block { char* name; uint32_t min_count; // ??? uint32_t max_count; uint32_t definition_size; uint8_t pad[4]; uint32_t definition_offset; //void* definition; // this is a void pointer, but I use it for parsing purposes as a uint32_t static file offset }; struct entry_block_field { enum datatypes type; char* label; struct entry_block definition; // pointer }; // This is an older interpretation I did from looking at guerilla.exe in memory. I don't use this in this program. struct entry_array_memory { char* name; uint32_t is_deep; // (has sub-arrays, sub-data, or dependencies) uint32_t max_count; uint32_t max_bytes; // with tag class, excludes 64 bytes of header uint8_t pad[4]; void* definition; }; // Arrays here are repeated cells of data whose definitions consist of all fields between array_start and array_end fields. If the fields are presented at all, if they have a visible string, the group of intermediary fields is repeated the number of times stored in repetitions. struct entry_array_start_field { enum datatypes type; char* name; uint32_t repetitions; }; struct entry_array_end_field { enum datatypes type; uint8_t pad[8]; }; struct entry_data { char* name; uint32_t interface_flags; uint32_t max_bytes; // with tag class, excludes 64 bytes of header uint8_t pad[4]; }; struct entry_data_field { enum datatypes type; char* label; struct entry_data definition; // pointer }; struct entry_custom_field { enum datatypes type; uint8_t pad[4]; char field_class[4]; }; struct tag_block { char* name; uint8_t pad_1[4]; uint32_t count; // always 1? uint32_t size; // excludes 64 bytes of header uint8_t pad_2[4]; uint32_t chunks_offset; //void* chunks; // this is a void pointer, but I use it for parsing purposes as a uint32_t static file offset uint8_t pad_3[4]; uint32_t extra_data_1_offset; //void* extra1; uint8_t pad_4[4]; uint32_t extra_data_2_offset; //void* extra2; }; struct tag_info { char* file_extension; int32_t unknown; char class[4]; char superclass[4]; int32_t version; uint32_t extra_data_offset; //void* extra; // pointer to some extra data struct tag_block* definition; }; struct file_data store_file(const char *path) { struct file_data result = { 0, calloc(1, sizeof(size_t)) }; if (path == NULL) return result; FILE* file = fopen(path, "r"); if (file == NULL) return result; if (fseek(file, 0, SEEK_END) != 0) { fclose(file); return result; } long filesize = ftell(file); if (filesize == -1 || filesize == 0) { fclose(file); return result; } void *data = calloc(1, (size_t)filesize); if (data == NULL) { fclose(file); return result; } rewind(file); if (fread(data, (size_t)filesize, 1, file) != 1) { free(data); fclose(file); return result; } fclose(file); result.length = (size_t)filesize; result.bytes = data; return result; } // returns the number of equivalent bytes, unlike memcmp size_t compare_bytes(const void* given1, const void* given2, size_t length) { if (given1 == NULL || given2 == NULL || length <= 0) return 0; for (size_t i = 0; i < length; i++) { if (*(uint8_t*)(given1 + i) != *(uint8_t*)(given2 + i)) return i; } return length; } bool contains_nonzero_bytes(const void* data, size_t data_length) { if (data != NULL && data_length > 0) { for (size_t i = 0; i < data_length; i++) { if (*(uint8_t*)(data + i) != 0) return true; } } return false; } // based upon https://stackoverflow.com/a/785681/2846508 // does not work with constant strings; will work with arrays (that are null-terminated) but not with this: char *s="actr" void reverse_string(char* s) { if (s != NULL && *s != '\0') { char temp, *end = s + strlen(s); while ( --end > s ) { temp = *s; *s++ = *end; *end=temp; } } } void reverse_bytes(void* data, size_t data_length) { if (data != NULL && data_length > 1) { uint8_t temp, *point1 = data, *point2 = data + data_length; while ( --point2 > point1 ) { temp = *point1; *(point1++) = *point2; *point2 = temp; } } } // convert static pointer address to HEK program binary offset // this lets me interpret all pointers as file data offsets in the file data bytes array, or use pointer math with void* bytes uint32_t p2o(const void* given) { if (given == NULL) return 0; return *(uint32_t*)given - MEMREGION; } char* o2string(struct file_data file, uint32_t offset) { return (char*)((uint8_t*)file.bytes + p2o((uint8_t*)file.bytes + offset)); } char* o2directstring(struct file_data file, uint32_t offset) { return (char*)((uint8_t*)file.bytes + (offset - MEMREGION)); } void* o2pointer(struct file_data file, uint32_t offset) { return (void*)((uint8_t*)file.bytes + p2o((uint8_t*)file.bytes + offset)); } int32_t int32val(struct file_data file, uint32_t offset) { int32_t result = 0; if (file.bytes != NULL && (offset + sizeof(int32_t) <= file.length)) memcpy(&result, (uint8_t*)file.bytes + offset, sizeof(int32_t)); return result; } uint32_t uint32val(struct file_data file, uint32_t offset) { uint32_t result = 0; if (file.bytes != NULL && (offset + sizeof(uint32_t) <= file.length)) memcpy(&result, (uint8_t*)file.bytes + offset, sizeof(uint32_t)); return result; } void o2array(struct file_data file, uint32_t offset, void* array, size_t array_length, bool reverse) { if (array == NULL) { array = calloc(1, array_length); } if ((file.bytes != NULL) && (offset + array_length <= file.length) && (array != NULL)) { memcpy(array, (uint8_t*)file.bytes + offset, array_length); if (reverse == true) reverse_bytes(array, array_length); } } void data_to_tagblock(struct file_data file, uint32_t offset, struct tag_block* destination) { destination->name = o2string(file, offset); offset += 4; o2array(file, offset, destination->pad_1, sizeof(destination->pad_1), false); offset += sizeof(destination->pad_1); destination->count = uint32val(file, offset); offset += 4; destination->size = uint32val(file, offset); offset += 4; o2array(file, offset, destination->pad_2, sizeof(destination->pad_2), false); offset += sizeof(destination->pad_2); destination->chunks_offset = p2o((uint8_t*)file.bytes + offset); offset += 4; o2array(file, offset, destination->pad_3, sizeof(destination->pad_3), false); offset += sizeof(destination->pad_3); destination->extra_data_1_offset = uint32val(file, offset); offset += 4; o2array(file, offset, destination->pad_4, sizeof(destination->pad_4), false); offset += sizeof(destination->pad_4); destination->extra_data_2_offset = uint32val(file, offset); } void data_to_taginfo(struct file_data file, uint32_t offset, struct tag_info* destination, uint32_t entry_index) { destination->file_extension = o2string(file, offset); offset += 4; destination->unknown = int32val(file, offset); offset += 4; o2array(file, offset, destination->class, sizeof(destination->class), true); offset += 4; o2array(file, offset, destination->superclass, sizeof(destination->superclass), true); offset += 4; destination->version = int32val(file, offset); offset += 4; destination->extra_data_offset = uint32val(file, offset); offset += 4; destination->definition = calloc(1, sizeof(struct tag_block)); data_to_tagblock(file, p2o((uint8_t*)file.bytes + offset), destination->definition); min_filesizes[entry_index] = 64 + destination->definition->size; max_filesizes[entry_index] = 64 + destination->definition->size; } struct entry_flags_info get_flags(struct file_data file, uint32_t offset) { struct entry_flags_info result; if (file.bytes != NULL && (offset + 8 <= file.length)) { result.count = uint32val(file, offset); result.names = (char*(*)[])((uint8_t*)file.bytes + offset + 4); } return result; } struct entry_block get_block(struct file_data file, uint32_t offset) { struct entry_block result; if (file.bytes != NULL && (offset + 24 <= file.length)) { result.name = o2string(file, offset); result.min_count = uint32val(file, offset + 4); result.max_count = uint32val(file, offset + 8); result.definition_size = uint32val(file, offset + 12); o2array(file, offset + 16, result.pad, sizeof(result.pad), false); result.definition_offset = uint32val(file, offset + 20) - MEMREGION; } return result; } void release(struct tag_info* taginfo) { // free every use of calloc free(taginfo->definition); free(taginfo); } void indent(int levels) { for (int i=0; i<levels; i++) { printf("\t"); } } void print_hex_string_from_bytes(const void* bytes, size_t length) { if (bytes == NULL || length == 0) return; char* result = calloc(1, length*3 + 1); if (result == NULL) return; size_t char_offset = 0; for (size_t i = 0; i < length; i++) { // for each byte, set the two characters based upon hexadecimal string result[char_offset] = hex[*((uint8_t*)bytes + i) >> 4 & 0xF]; char_offset += 1; result[char_offset] = hex[*((uint8_t*)bytes + i) & 0xF]; char_offset += 1; if (i + 1 < length) { result[char_offset] = ':'; char_offset += 1; } } printf("%s\n",result); free(result); } void describe_tagblock(struct tag_block* tagblock, int levels) { indent(levels); //printf("struct %s\n",tagblock->name); //indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Name: %s\n",tagblock->name); if (contains_nonzero_bytes(tagblock->pad_1, sizeof(tagblock->pad_1))) { indent(levels); printf("Pad 1: "); print_hex_string_from_bytes(tagblock->pad_1, sizeof(tagblock->pad_1)); } indent(levels); printf("Count: %u\n",tagblock->count); indent(levels); printf("Size: %u\n",tagblock->size); if (contains_nonzero_bytes(tagblock->pad_2, sizeof(tagblock->pad_2))) { indent(levels); printf("Pad 2: "); print_hex_string_from_bytes(tagblock->pad_2, sizeof(tagblock->pad_2)); } indent(levels); printf("Chunks Offset: 0x%x\n",tagblock->chunks_offset); if (contains_nonzero_bytes(tagblock->pad_3, sizeof(tagblock->pad_3))) { indent(levels); printf("Pad 3: "); print_hex_string_from_bytes(tagblock->pad_3, sizeof(tagblock->pad_3)); } if (contains_nonzero_bytes(&tagblock->extra_data_1_offset, sizeof(tagblock->extra_data_1_offset))) { indent(levels); printf("Dialog Data 1 Offset: 0x%x\n",tagblock->extra_data_1_offset); } if (contains_nonzero_bytes(tagblock->pad_4, sizeof(tagblock->pad_4))) { indent(levels); printf("Pad 4: "); print_hex_string_from_bytes(tagblock->pad_4, sizeof(tagblock->pad_4)); } if (contains_nonzero_bytes(&tagblock->extra_data_2_offset, sizeof(tagblock->extra_data_2_offset))) { indent(levels); printf("Dialog Data 2 Offset: 0x%x\n",tagblock->extra_data_2_offset); } levels -= 1; indent(levels); printf("}\n"); } void describe_taginfo(struct tag_info* taginfo) { // print tag info using number of nested (indented) levels printf("Extension: %s\n", taginfo->file_extension); printf("Unknown: %i\n", taginfo->unknown); printf("Class: %c%c%c%c\n", taginfo->class[0], taginfo->class[1], taginfo->class[2], taginfo->class[3]); if (compare_bytes(taginfo->superclass, negone, 4) == 4) printf("No superclass\n"); else printf("Superclass: %c%c%c%c\n", taginfo->superclass[0], taginfo->superclass[1], taginfo->superclass[2], taginfo->superclass[3]); printf("Version: %i\n", taginfo->version); if (contains_nonzero_bytes(&taginfo->extra_data_offset, sizeof(taginfo->extra_data_offset))) { printf("Dialog Data Offset: 0x%x\n", taginfo->extra_data_offset); } printf("Definition Block:\n"); describe_tagblock(taginfo->definition, 0); } struct temp_entry { enum datatypes type; char* name; uint32_t something; }; struct temp_entry read_entry(struct file_data file, uint32_t offset) { struct temp_entry result; result.type = uint32val(file, offset); result.name = o2string(file, offset + 4); result.something = uint32val(file, offset + 8); return result; } void print_fields_in_c(struct file_data file, uint32_t offset, int levels, uint32_t entry_index) { //int entry_index = 0; while (true) { if (offset + 12 > file.length) return; // file data too short struct temp_entry entry = read_entry(file, offset); offset += 12; switch (entry.type) { case datatype_string: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("string %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_char_integer: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("char_integer %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_short_integer: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("short_integer %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("(used as a short_block_index)\n"); indent(levels); printf("Block Name: %s\n", o2string(file, entry.something - MEMREGION)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_long_integer: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("long_integer %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("(used as a long_block_index)\n"); indent(levels); printf("Block Name: %s\n", o2string(file, entry.something - MEMREGION)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_angle: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("angle %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_tag: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("tag %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_enum: { struct entry_flags_field flags = { entry.type, entry.name }; indent(levels); printf("enum %s\n", flags.name); indent(levels); printf("{\n"); levels += 1; flags.info = get_flags(file, entry.something - MEMREGION); for (int i = 0; i < flags.info.count; i++) { indent(levels); printf("%s\n",o2string(file, p2o(flags.info.names) + (i * sizeof(uint32_t)))); } levels -= 1; indent(levels); printf("}\n"); break; } case datatype_long_flags: { struct entry_flags_field flags = { entry.type, entry.name }; indent(levels); printf("long_flags %s\n", flags.name); indent(levels); printf("{\n"); levels += 1; flags.info = get_flags(file, entry.something - MEMREGION); for (int i = 0; i < flags.info.count; i++) { indent(levels); printf("%s\n",o2string(file, p2o(flags.info.names) + (i * sizeof(uint32_t)))); } levels -= 1; indent(levels); printf("}\n"); break; } case datatype_word_flags: { struct entry_flags_field flags = { entry.type, entry.name }; indent(levels); printf("word_flags %s\n", flags.name); indent(levels); printf("{\n"); levels += 1; flags.info = get_flags(file, entry.something - MEMREGION); for (int i = 0; i < flags.info.count; i++) { indent(levels); printf("%s\n",o2string(file, p2o(flags.info.names) + (i * sizeof(uint32_t)))); } levels -= 1; indent(levels); printf("}\n"); break; } case datatype_byte_flags: { struct entry_flags_field flags = { entry.type, entry.name }; indent(levels); printf("byte_flags %s\n", flags.name); indent(levels); printf("{\n"); levels += 1; flags.info = get_flags(file, entry.something - MEMREGION); for (int i = 0; i < flags.info.count; i++) { indent(levels); printf("%s\n",o2string(file, p2o(flags.info.names) + (i * sizeof(uint32_t)))); } levels -= 1; indent(levels); printf("}\n"); break; } case datatype_point_2d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("point_2d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_rectangle_2d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("rectangle_2d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_rgb_color: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("rgb_color %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_argb_color: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("argb_color %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); // change this to be a comment (#) later printf("Hidden documentation: %s\n", o2directstring(file, entry.something)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_fraction: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_fraction %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_point_2d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_point_2d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_point_3d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_point_3d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_vector_2d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_vector_2d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_vector_3d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_vector_3d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_quaternion: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_quaternion %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_euler_angles_2d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_euler_angles_2d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_euler_angles_3d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_euler_angles_3d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_plane_2d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_plane_2d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_plane_3d: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_plane_3d %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_rgb_color: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_rgb_color %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_argb_color: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_argb_color %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_hsv_color: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_hsv_color %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_ahsv_color: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_ahsv_color %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_short_integer_bounds: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("short_integer_bounds %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_angle_bounds: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("angle_bounds %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_real_bounds: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("real_bounds %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_fraction_bounds: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("fraction_bounds %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(&entry.something, sizeof(uint32_t)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_tag_reference: { struct entry_dependency_field dependency = { entry.type, entry.name }; indent(levels); printf("tag reference %s\n", dependency.name); struct entry_dependency_info x; x.usage_flags = uint32val(file, entry.something - MEMREGION); o2array(file, entry.something - MEMREGION + 4, x.class, sizeof(x.class), true); o2array(file, entry.something - MEMREGION + 8, x.pad_2, sizeof(x.pad_2), false); dependency.definition = x; indent(levels); printf("{\n"); levels += 1; bool explicit_types = false; if (contains_nonzero_bytes(&dependency.definition.usage_flags, sizeof(dependency.definition.usage_flags))) { indent(levels); printf("Usage flags value: %u\n", dependency.definition.usage_flags); } if (compare_bytes(dependency.definition.class, negone, 4) != 4) { indent(levels); printf("Supported tag class category: %c%c%c%c\n", dependency.definition.class[0], dependency.definition.class[1], dependency.definition.class[2], dependency.definition.class[3]); } else { // if this is -1, then there is a specific list of supported tag classes explicit_types = true; uint32_t zero = 0; if (compare_bytes(dependency.definition.pad_2, &zero, 4) == 4) { // if this is zero, then there is no given list, meaning all tag classes are listed as supported indent(levels); printf("Supports all tag classes\n"); } else { uint32_t list_offset = 0; memcpy(&list_offset, dependency.definition.pad_2, sizeof(uint32_t)); list_offset -= MEMREGION; do { o2array(file, list_offset, dependency.definition.class, sizeof(dependency.definition.class), true); if (compare_bytes(dependency.definition.class, negone, 4) == 4) break; indent(levels); printf("Supported tag class: %c%c%c%c\n", dependency.definition.class[0], dependency.definition.class[1], dependency.definition.class[2], dependency.definition.class[3]); list_offset += 4; } while (compare_bytes(dependency.definition.class, negone, 4) != 4); } } if (explicit_types == false && contains_nonzero_bytes(dependency.definition.pad_2, sizeof(dependency.definition.pad_2))) { indent(levels); printf("Padding 2: "); print_hex_string_from_bytes(dependency.definition.pad_2, sizeof(dependency.definition.pad_2)); } levels -= 1; indent(levels); printf("}\n"); max_filesizes[entry_index] += 255; // for tpns of max length break; } case datatype_block: { struct entry_block_field block = { entry.type, entry.name, get_block(file, entry.something - MEMREGION) }; indent(levels); printf("block %s\n", block.label); indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Name: %s\n", block.definition.name); if (contains_nonzero_bytes(&block.definition.min_count, sizeof(block.definition.min_count))) { indent(levels); printf("Unknown: "); print_hex_string_from_bytes(&block.definition.min_count, sizeof(block.definition.min_count)); } indent(levels); printf("Max Chunks: %u\n", block.definition.max_count); indent(levels); printf("Chunk Size: %u\n", block.definition.definition_size); indent(levels); printf("Max Chunks x Chunk Size: %u\n", (block.definition.max_count * block.definition.definition_size)); max_filesizes[entry_index] += (block.definition.max_count * block.definition.definition_size); // this might not work properly with nested blocks... if (contains_nonzero_bytes(block.definition.pad, sizeof(block.definition.pad))) { indent(levels); printf("Pad: "); print_hex_string_from_bytes(block.definition.pad, sizeof(block.definition.pad)); } indent(levels); printf("Chunk Definition Offset: 0x%x\n", block.definition.definition_offset); indent(levels); printf("{\n"); levels += 1; print_fields_in_c(file, block.definition.definition_offset, levels, entry_index); levels -= 1; indent(levels); printf("}\n"); levels -= 1; indent(levels); printf("}\n"); break; } case datatype_short_block_index: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("short_block_index %s\n", number.name); // entry.something is a definition pointer (for parsing) if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Block Name: %s\n", o2string(file, entry.something - MEMREGION)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_long_block_index: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("long_block_index %s\n", number.name); // entry.something is a definition pointer (for parsing) if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Block Name: %s\n", o2string(file, entry.something - MEMREGION)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_data: { struct entry_data_field data_field = { entry.type, entry.name }; struct entry_data x; x.name = o2string(file, entry.something - MEMREGION); x.interface_flags = uint32val(file, entry.something - MEMREGION + 4); x.max_bytes = uint32val(file, entry.something - MEMREGION + 8); o2array(file, entry.something - MEMREGION + 12, x.pad, sizeof(x.pad), false); data_field.definition = x; indent(levels); printf("data %s\n", data_field.label); indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Definition Name: %s\n", data_field.definition.name); if (contains_nonzero_bytes(&data_field.definition.interface_flags, sizeof(uint32_t))) { indent(levels); printf("Interface Flags: %u\n", data_field.definition.interface_flags); } indent(levels); printf("Max Bytes: %u\n", data_field.definition.max_bytes); if (contains_nonzero_bytes(data_field.definition.pad, sizeof(data_field.definition.pad))) { indent(levels); printf("Extra Data Offset: 0x%x\n", *(uint32_t*)data_field.definition.pad - MEMREGION); } levels -= 1; indent(levels); printf("}\n"); max_filesizes[entry_index] += x.max_bytes; break; } case datatype_array_start: { struct entry_array_start_field array_start = { entry.type, entry.name, entry.something }; indent(levels); printf("array_start \"%s\" repeated %u time(s):\n", array_start.name, array_start.repetitions); levels += 1; break; } case datatype_array_end: { struct entry_array_end_field array_end = { entry.type }; memcpy(array_end.pad, (uint8_t*)file.bytes + (offset - 8), sizeof(array_end.pad)); levels -= 1; indent(levels); printf("array_end \n"); if (contains_nonzero_bytes(array_end.pad, sizeof(array_end.pad))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Padding: "); print_hex_string_from_bytes(array_end.pad, sizeof(array_end.pad)); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_pad: { struct entry_pad_field pad; pad.type = entry.type; memcpy(pad.pad, (uint8_t*)file.bytes + (offset - 8), sizeof(pad.pad)); pad.size = entry.something; indent(levels); printf("pad[%u]\n", pad.size); if (contains_nonzero_bytes(pad.pad, sizeof(pad.pad))) { indent(levels); printf("{\n"); levels += 1; indent(levels); // change this to be a comment (#) later printf("Hidden documentation (field name?): %s\n", entry.name); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_skip: { struct entry_pad_field pad; pad.type = entry.type; memcpy(pad.pad, (uint8_t*)file.bytes + (offset - 8), sizeof(pad.pad)); pad.size = entry.something; indent(levels); printf("skip[%u]\n", pad.size); if (contains_nonzero_bytes(pad.pad, sizeof(pad.pad))) { indent(levels); printf("{\n"); levels += 1; indent(levels); // change this to be a comment (#) later printf("Hidden documentation (field name?): %s\n", entry.name); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_explanation: { struct entry_number_field number = { entry.type, entry.name }; indent(levels); printf("explanation %s\n", number.name); if (contains_nonzero_bytes(&entry.something, sizeof(uint32_t))) { indent(levels); printf("{\n"); levels += 1; indent(levels); printf("Dialog Data Offset: 0x%x\n", entry.something - MEMREGION); indent(levels); printf("{\n"); //levels += 1; //indent(levels); printf("%s\n", o2directstring(file, entry.something)); //levels -= 1; indent(levels); printf("}\n"); levels -= 1; indent(levels); printf("}\n"); } break; } case datatype_custom: { struct entry_custom_field custom; custom.type = entry.type; memcpy(custom.pad, (uint8_t*)file.bytes + (offset - 8), sizeof(custom.pad)); memcpy(custom.field_class, (uint8_t*)file.bytes + (offset - 4), sizeof(custom.field_class)); reverse_bytes(custom.field_class, sizeof(custom.field_class)); indent(levels); printf("custom\n"); indent(levels); printf("{\n"); levels += 1; if (contains_nonzero_bytes(custom.pad, sizeof(custom.pad))) { indent(levels); printf("Padding: "); print_hex_string_from_bytes(custom.pad, sizeof(custom.pad)); } if (contains_nonzero_bytes(custom.field_class, sizeof(custom.field_class))) { indent(levels); printf("Field Class: %c%c%c%c\n", custom.field_class[0], custom.field_class[1], custom.field_class[2], custom.field_class[3]); } levels -= 1; indent(levels); printf("}\n"); break; } case datatype_terminator_X: { return; } default: { indent(levels); printf("***UNKNOWN DATATYPE***\n"); break; } } } } // the purpose of this program is to output in C the tag file definitions from within an HEK program. int main(int argc, const char * argv[]) { @autoreleasepool { if (argc < 2) return 0; struct file_data file = store_file(argv[1]); //NSFileManager *fm = [NSFileManager new]; //NSData *filedata = [fm contentsAtPath:[NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding]]; if (file.bytes == NULL) return 1; // get all the tag definition file data offsets if (file.length < GUERILLA_DEFS_INDEX + (83 * sizeof(uint32_t))) return 1; uint32_t tag_def_offsets[83] = { 0 }; printf("extracthalotagdefs and its resulting file are by sparky (e-mail:galaxyverge+halo@pm.me discord:sparky#0343 chat:https://discord.gg/mcEzrrv)\ntetelestai\ntag definitions parsed from guerilla.exe\nmodify output to suit your source code syntax needs by modifying extracthalotagdefs\nall credit to Jesus Christ for anything that pleases His Majesty, King of Glory\nnote that these definitions do not fully equate to stored file data...\nrespect me and what I freely did for you by leaving this printf statement intact\n\n"); for (uint32_t i = 0; i < 83; i++) { tag_def_offsets[i] = p2o((uint8_t*)file.bytes + GUERILLA_DEFS_INDEX + (i * sizeof(uint32_t))); printf("Tag Definition Offset: 0x%x\n",tag_def_offsets[i]); if (tag_def_offsets[i] >= file.length) return 1; // unusable data offset check, in case the supplied file has unexpected data // parse and output into string struct tag_info *tagdef = calloc(1, sizeof(struct tag_info)); if (tagdef == NULL) return 2; // couldn't allocate memory during calloc data_to_taginfo(file, tag_def_offsets[i], tagdef, i); describe_taginfo(tagdef); print_fields_in_c(file, tagdef->definition->chunks_offset, 1, i); printf("POORLY-DETERMINED MIN FILESIZE OF %c%c%c%c (including 64-byte header): %u\n", tagdef->class[0], tagdef->class[1], tagdef->class[2], tagdef->class[3], min_filesizes[i]); printf("POORLY-DETERMINED MAX FILESIZE OF %c%c%c%c (including 64-byte header): %u\n", tagdef->class[0], tagdef->class[1], tagdef->class[2], tagdef->class[3], max_filesizes[i]); printf("\n"); release(tagdef); } } return 0; }
Optional Paste Settings
Category:
None
Cryptocurrency
Cybersecurity
Fixit
Food
Gaming
Haiku
Help
History
Housing
Jokes
Legal
Money
Movies
Music
Pets
Photo
Science
Software
Source Code
Spirit
Sports
Travel
TV
Writing
Tags:
Syntax Highlighting:
None
Bash
C
C#
C++
CSS
HTML
JSON
Java
JavaScript
Lua
Markdown (PRO members only)
Objective C
PHP
Perl
Python
Ruby
Swift
4CS
6502 ACME Cross Assembler
6502 Kick Assembler
6502 TASM/64TASS
ABAP
AIMMS
ALGOL 68
APT Sources
ARM
ASM (NASM)
ASP
ActionScript
ActionScript 3
Ada
Apache Log
AppleScript
Arduino
Asymptote
AutoIt
Autohotkey
Avisynth
Awk
BASCOM AVR
BNF
BOO
Bash
Basic4GL
Batch
BibTeX
Blitz Basic
Blitz3D
BlitzMax
BrainFuck
C
C (WinAPI)
C Intermediate Language
C for Macs
C#
C++
C++ (WinAPI)
C++ (with Qt extensions)
C: Loadrunner
CAD DCL
CAD Lisp
CFDG
CMake
COBOL
CSS
Ceylon
ChaiScript
Chapel
Clojure
Clone C
Clone C++
CoffeeScript
ColdFusion
Cuesheet
D
DCL
DCPU-16
DCS
DIV
DOT
Dart
Delphi
Delphi Prism (Oxygene)
Diff
E
ECMAScript
EPC
Easytrieve
Eiffel
Email
Erlang
Euphoria
F#
FO Language
Falcon
Filemaker
Formula One
Fortran
FreeBasic
FreeSWITCH
GAMBAS
GDB
GDScript
Game Maker
Genero
Genie
GetText
Go
Godot GLSL
Groovy
GwBasic
HQ9 Plus
HTML
HTML 5
Haskell
Haxe
HicEst
IDL
INI file
INTERCAL
IO
ISPF Panel Definition
Icon
Inno Script
J
JCL
JSON
Java
Java 5
JavaScript
Julia
KSP (Kontakt Script)
KiXtart
Kotlin
LDIF
LLVM
LOL Code
LScript
Latex
Liberty BASIC
Linden Scripting
Lisp
Loco Basic
Logtalk
Lotus Formulas
Lotus Script
Lua
M68000 Assembler
MIX Assembler
MK-61/52
MPASM
MXML
MagikSF
Make
MapBasic
Markdown (PRO members only)
MatLab
Mercury
MetaPost
Modula 2
Modula 3
Motorola 68000 HiSoft Dev
MySQL
Nagios
NetRexx
Nginx
Nim
NullSoft Installer
OCaml
OCaml Brief
Oberon 2
Objeck Programming Langua
Objective C
Octave
Open Object Rexx
OpenBSD PACKET FILTER
OpenGL Shading
Openoffice BASIC
Oracle 11
Oracle 8
Oz
PARI/GP
PCRE
PHP
PHP Brief
PL/I
PL/SQL
POV-Ray
ParaSail
Pascal
Pawn
Per
Perl
Perl 6
Phix
Pic 16
Pike
Pixel Bender
PostScript
PostgreSQL
PowerBuilder
PowerShell
ProFTPd
Progress
Prolog
Properties
ProvideX
Puppet
PureBasic
PyCon
Python
Python for S60
QBasic
QML
R
RBScript
REBOL
REG
RPM Spec
Racket
Rails
Rexx
Robots
Roff Manpage
Ruby
Ruby Gnuplot
Rust
SAS
SCL
SPARK
SPARQL
SQF
SQL
SSH Config
Scala
Scheme
Scilab
SdlBasic
Smalltalk
Smarty
StandardML
StoneScript
SuperCollider
Swift
SystemVerilog
T-SQL
TCL
TeXgraph
Tera Term
TypeScript
TypoScript
UPC
Unicon
UnrealScript
Urbi
VB.NET
VBScript
VHDL
VIM
Vala
Vedit
VeriLog
Visual Pro Log
VisualBasic
VisualFoxPro
WHOIS
WhiteSpace
Winbatch
XBasic
XML
XPP
Xojo
Xorg Config
YAML
YARA
Z80 Assembler
ZXBasic
autoconf
jQuery
mIRC
newLISP
q/kdb+
thinBasic
Paste Expiration:
Never
Burn after read
10 Minutes
1 Hour
1 Day
1 Week
2 Weeks
1 Month
6 Months
1 Year
Paste Exposure:
Public
Unlisted
Private
Folder:
(members only)
Password
NEW
Enabled
Disabled
Burn after read
NEW
Paste Name / Title:
Create New Paste
Hello
Guest
Sign Up
or
Login
Sign in with Facebook
Sign in with Twitter
Sign in with Google
You are currently not logged in, this means you can not edit or delete anything you paste.
Sign Up
or
Login
Public Pastes
F-Formula
2 hours ago | 1.23 KB
SEEING GOD IN THE MATH
3 hours ago | 0.12 KB
Untitled
18 hours ago | 1.88 KB
Untitled
18 hours ago | 0.67 KB
Untitled
18 hours ago | 3.33 KB
Untitled
18 hours ago | 1.00 KB
Untitled
18 hours ago | 0.33 KB
Untitled
18 hours ago | 1.55 KB
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the
Cookies Policy
.
OK, I Understand
Not a member of Pastebin yet?
Sign Up
, it unlocks many cool features!