#include #include static std::vector sounds = { "PCM_cloth1", "PCM_cloth2", "PCM_cloth3", "PCM_cloth4", "PCM_grass1", "PCM_grass2", "PCM_grass3", "PCM_grass4", "PCM_gravel1", "PCM_gravel2", "PCM_gravel3", "PCM_gravel4", "PCM_sand1", "PCM_sand2", "PCM_sand3", "PCM_sand4", "PCM_stone1", "PCM_stone2", "PCM_stone3", "PCM_stone4", "PCM_wood1", "PCM_wood2", "PCM_wood3", "PCM_wood4", "PCM_splash", "PCM_explode", "PCM_click", "PCM_door_open", "PCM_door_close", "PCM_pop", "PCM_pop2", "PCM_hurt", "PCM_glass1", "PCM_glass2", "PCM_glass3", "PCM_sheep1", "PCM_sheep2", "PCM_sheep3", "PCM_pig1", "PCM_pig2", "PCM_pig3", "PCM_pigdeath", "PCM_cow1", "PCM_cow2", "PCM_cow3", "PCM_cow4", "PCM_cowhurt1", "PCM_cowhurt2", "PCM_cowhurt3", "PCM_chicken2", "PCM_chicken3", "PCM_chickenhurt1", "PCM_chickenhurt2", "PCM_zombie1", "PCM_zombie2", "PCM_zombie3", "PCM_zombiedeath", "PCM_zombiehurt1", "PCM_zombiehurt2", "PCM_skeleton1", "PCM_skeleton2", "PCM_skeleton3", "PCM_skeletonhurt1", "PCM_skeletonhurt2", "PCM_skeletonhurt3", "PCM_skeletonhurt4", "PCM_spider1", "PCM_spider2", "PCM_spider3", "PCM_spider4", "PCM_spiderdeath", "PCM_zpig1", "PCM_zpig2", "PCM_zpig3", "PCM_zpig4", "PCM_zpigangry1", "PCM_zpigangry2", "PCM_zpigangry3", "PCM_zpigangry4", "PCM_zpigdeath", "PCM_zpighurt1", "PCM_zpighurt2", "PCM_fallbig1", "PCM_fallbig2", "PCM_fallsmall", "PCM_bow", "PCM_bowhit1", "PCM_bowhit2", "PCM_bowhit3", "PCM_bowhit4", "PCM_creeper1", "PCM_creeper2", "PCM_creeper3", "PCM_creeper4", "PCM_creeperdeath", "PCM_eat1", "PCM_eat2", "PCM_eat3", "PCM_fuse", "PCM_burp", "PCM_fizz", "PCM_drink", "PCM_chestopen", "PCM_chestclosed" }; #include #include #include #include #include #include #include #define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", __VA_ARGS__); } #define ERR(format, ...) { fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, __VA_ARGS__); exit(EXIT_FAILURE); } // Load Symbol From ELF File static void load_symbol(const char *source, const char *name, std::function callback) { // File Data FILE *file_obj = NULL; unsigned char *file_map = NULL; long int file_size = 0; // Code { // Load Main Binary file_obj = fopen(source, "rb"); // Verify Binary if (!file_obj) { WARN("Unable To Open: %s", source); goto end; } // Get File Size fseek(file_obj, 0L, SEEK_END); file_size = ftell(file_obj); fseek(file_obj, 0L, SEEK_SET); // Map File To Pointer file_map = (unsigned char *) mmap(0, file_size, PROT_READ, MAP_PRIVATE, fileno(file_obj), 0); // Check ELF Magic if (file_map[EI_MAG0] != ELFMAG0 || file_map[EI_MAG1] != ELFMAG1 || file_map[EI_MAG2] != ELFMAG2 || file_map[EI_MAG3] != ELFMAG3) { WARN("Not An ELF File: %s", source); goto end; } if (file_map[EI_CLASS] != ELFCLASS32) { WARN("ELF File Isn't 32-Bit: %s", source); goto end; } if (file_map[EI_DATA] != ELFDATA2LSB) { WARN("ELF File Isn't Little-Endian: %s", source); goto end; } // Parse ELF Elf32_Ehdr *elf_header = (Elf32_Ehdr *) file_map; Elf32_Shdr *elf_section_headers = (Elf32_Shdr *) (file_map + elf_header->e_shoff); int elf_section_header_count = elf_header->e_shnum; // Locate Section Names Elf32_Shdr elf_shstrtab = elf_section_headers[elf_header->e_shstrndx]; unsigned char *elf_shstrtab_p = file_map + elf_shstrtab.sh_offset; // Locate String Table unsigned char *elf_strtab_p = NULL; for (int i = 0; i < elf_section_header_count; ++i) { Elf32_Shdr header = elf_section_headers[i]; // Check Section Type if (header.sh_type == SHT_STRTAB) { // Check Section Name char *section_name = (char *) (elf_shstrtab_p + header.sh_name); if (strcmp(section_name, ".dynstr") == 0) { // Found elf_strtab_p = file_map + header.sh_offset; break; } } } if (elf_strtab_p == NULL) { WARN("Unable To Find String Table In: %s", source); goto end; } // Locate Symbol Tables Elf32_Sym *symbol = NULL; for (int i = 0; i < elf_section_header_count; ++i) { // Exit Loop If Finished if (symbol != NULL) { break; } // Get Section Header Elf32_Shdr header = elf_section_headers[i]; // Check Section Type if (header.sh_type == SHT_DYNSYM) { // Symbol Table Elf32_Sym *table = (Elf32_Sym *) (file_map + header.sh_offset); for (int j = 0; (j * sizeof (Elf32_Sym)) < header.sh_size; j++) { // Check Symbol Name char *symbol_name = (char *) (elf_strtab_p + table[j].st_name); if (strcmp(symbol_name, name) == 0) { // Found symbol = &table[j]; break; } } } } // Check Symbol if (symbol != NULL) { // Convert Virtual Address To File Offset Elf32_Shdr symbol_section_header = elf_section_headers[symbol->st_shndx]; int vaddr_to_offset = -symbol_section_header.sh_addr + symbol_section_header.sh_offset; Elf32_Off symbol_offset = symbol->st_value + vaddr_to_offset; // Access Symbol unsigned char *value = file_map + symbol_offset; uint32_t size = symbol->st_size; callback(value, size); } else { // Unable To Find Symbol WARN("Unable To Find Symbol: %s", name); } } end: // Unmap And Close File if (file_map != NULL) { munmap(file_map, file_size); } if (file_obj != NULL) { fclose(file_obj); } } // Main int main(int argc, char *argv[]) { if (argc != 2) { ERR("%s", "Invalid Arguments"); } for (std::string sound : sounds) { load_symbol(argv[1], sound.c_str(), [sound](unsigned char *symbol, uint32_t size) { printf("const unsigned char %s[] = {", sound.c_str()); for (uint32_t i = 0; i < size; i++) { printf("%u", (unsigned int) symbol[i]); if (i < (size - 1)) { printf(", "); } } printf("};\n"); }); } }