/** Unparse the Frame Description Entry (FDE) into a string but do not include the leading length field(s) or the CIE back * pointer. */ std::string SgAsmElfEHFrameEntryFD::unparse(const SgAsmElfEHFrameSection *ehframe, SgAsmElfEHFrameEntryCI *cie) const { SgAsmElfFileHeader *fhdr = ehframe->get_elf_header(); ROSE_ASSERT(fhdr!=NULL); /* Allocate worst-case size for results */ size_t worst_size = 8 + get_augmentation_data().size() + get_instructions().size() + fhdr->get_word_size(); unsigned char *buf = new unsigned char[worst_size]; size_t sz; rose_addr_t at = 0; uint32_t u32_disk; /* PC Begin (begin_rva) and size */ switch (cie->get_addr_encoding()) { case -1: /* No address encoding specified */ case 0x01: case 0x03: case 0x1b: { ByteOrder::host_to_le(get_begin_rva().get_rva(), &u32_disk); memcpy(buf+at, &u32_disk, 4); at+=4; ByteOrder::host_to_le(get_size(), &u32_disk); memcpy(buf+at, &u32_disk, 4); at+=4; break; } default: /* See parser */ if (++nwarnings<=WARNING_LIMIT) { fprintf(stderr, "%s:%u: warning: unknown FDE address encoding (0x%02x)\n", __FILE__, __LINE__, cie->get_addr_encoding()); if (WARNING_LIMIT==nwarnings) fprintf(stderr, " (additional frame warnings will be suppressed)\n"); } break; } /* Augmentation Data */ std::string astr = cie->get_augmentation_string(); if (astr.size()>0 && astr[0]=='z') { at = ehframe->write_uleb128(buf, at, get_augmentation_data().size()); sz = get_augmentation_data().size(); if (sz>0) { memcpy(buf+at, &(get_augmentation_data()[0]), sz); at += sz; } } /* Call frame instructions */ sz = get_instructions().size(); if (sz>0) { memcpy(buf+at, &(get_instructions()[0]), sz); at += sz; } std::string retval((char*)buf, at); delete[] buf; return retval; }
int main(int argc, char** args) { FILE* instruction_file = fopen(args[1], "r"); char** instructions = NULL; int lines = get_instructions(instruction_file, &instructions); fclose(instruction_file); var** input_variables = NULL; int num_input_variables = get_input_variables(instructions, lines, &input_variables); var** temp_variables = NULL; int num_temp_variables = get_temporary_variables(instructions, lines, &temp_variables); var** output_variables = NULL; int num_output_variables = get_output_variables(instructions, lines, &output_variables); FILE* value_file = fopen(args[2], "r"); char* string = (char *) malloc(256 * sizeof(char *)); while (fscanf(value_file, "%[^\n]\n", string) == 1) { int i; for (i = 0; i < num_input_variables; i++) { input_variables[i] -> value = string[i*2] - '0'; } run_program(instructions, lines, input_variables, num_input_variables, temp_variables, num_temp_variables, output_variables, num_output_variables ); } return 0; }
//The main part of the game running problems and movement etc. void run(roomGrid *rg, progress *pz) { SDL_Window *window = NULL; char *instructions_list[NUM_INSTRUCTIONS]; initialise_SDL_component(window, rg); get_instructions(instructions_list); Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, AUDIO_S16SYS, MUSIC_CONST_ONE, MUSIC_CONST_TWO); Mix_Chunk *mus = Mix_LoadWAV("20141124b.wav"); //Prints the opening scene. print_instruction(rg, instructions_list, 0, 10); draw(rg, pz, mus, instructions_list); atexit(SDL_Quit); //Mix_HaltMusic(); //Mix_FreeChunk(mus); //Mix_CloseAudio(); // Mix_Quit(); IMG_Quit(); SDL_Quit(); }
int treat_command(char *buff, t_cinfo *client_info) { char *arg; char *instr; int treated; char *error; arg = NULL; error = NULL; if (!(instr = get_instructions(buff))) return (send_error(client_info->sock, "ERROR: allocation failed.\n")); if (buff_has_arg(buff)) { if (!(arg = get_arg(buff))) return (send_error(client_info->sock, "ERROR: allocation failed.\n")); } else arg = NULL; // printf("buff = %s\n instr = %s\n arg = %s\n", buff, instr, arg); treated = 0; assign_behavior(instr, client_info, &treated, arg); if (check_if_cmd_treated(treated, client_info->sock, instr, error) == -1) return (-1); free(arg); free(instr); return (0); }
FatMethod* MethodTransform::balloon(DexMethod* method) { auto code = method->get_code(); if (code == nullptr) { return nullptr; } TRACE(MTRANS, 2, "Ballooning %s\n", SHOW(method)); auto opcodes = code->get_instructions(); addr_mei_t addr_to_mei; FatMethod* fm = new FatMethod(); uint32_t addr = 0; for (auto opcode : opcodes) { MethodItemEntry* mei = new MethodItemEntry(opcode); fm->push_back(*mei); addr_to_mei[addr] = mei; mei->addr = addr; TRACE(MTRANS, 5, "%08x: %s[mei %p]\n", addr, SHOW(opcode), mei); addr += opcode->size(); } generate_branch_targets(fm, addr_to_mei); associate_try_items(fm, code, addr_to_mei); auto debugitem = code->get_debug_item(); if (debugitem) { associate_debug_entries(fm, debugitem, addr_to_mei); } return fm; }
/** Print some debugging info */ void SgAsmElfEHFrameEntryFD::dump(FILE *f, const char *prefix, ssize_t idx) const { char p[4096]; if (idx>=0) { sprintf(p, "%sFDE[%zd].", prefix, idx); } else { sprintf(p, "%sFDE.", prefix); } const int w = std::max(1, DUMP_FIELD_WIDTH-(int)strlen(p)); fprintf(f, "%s%-*s = %s\n", p, w, "begin_rva", get_begin_rva().to_string().c_str()); fprintf(f, "%s%-*s = 0x%08"PRIx64" (%"PRIu64") bytes\n", p, w, "size", get_size(), get_size()); fprintf(f, "%s%-*s = 0x%08zx (%zu) bytes\n", p, w, "aug_data", get_augmentation_data().size(), get_augmentation_data().size()); hexdump(f, 0, std::string(p)+"data at ", get_augmentation_data()); fprintf(f, "%s%-*s = 0x%08zx (%zu) bytes\n", p, w, "instructions", get_instructions().size(), get_instructions().size()); hexdump(f, 0, std::string(p)+"insns at ", get_instructions()); }
/** Print some debugging info */ void SgAsmElfEHFrameEntryCI::dump(FILE *f, const char *prefix, ssize_t idx) const { char p[4096]; if (idx>=0) { sprintf(p, "%sCIE[%zd].", prefix, idx); } else { sprintf(p, "%sCIE.", prefix); } const int w = std::max(1, DUMP_FIELD_WIDTH-(int)strlen(p)); fprintf(f, "%s%-*s = %d\n", p, w, "version", get_version()); fprintf(f, "%s%-*s = \"%s\"\n", p, w, "augStr", get_augmentation_string().c_str()); fprintf(f, "%s%-*s = %s\n", p, w, "sig_frame", get_sig_frame()?"yes":"no"); fprintf(f, "%s%-*s = 0x%08"PRIx64" (%"PRIu64")\n", p, w, "code_align", get_code_alignment_factor(), get_code_alignment_factor()); fprintf(f, "%s%-*s = 0x%08"PRIx64" (%"PRId64")\n", p, w, "data_align", get_data_alignment_factor(), get_data_alignment_factor()); fprintf(f, "%s%-*s = 0x%08"PRIx64" (%"PRIu64")\n", p, w, "aug_length", get_augmentation_data_length(), get_augmentation_data_length()); fprintf(f, "%s%-*s = %d\n", p, w, "lsda_encoding", get_lsda_encoding()); fprintf(f, "%s%-*s = %d\n", p, w, "prh_encoding", get_prh_encoding()); if (get_prh_encoding()>=0) { fprintf(f, "%s%-*s = 0x%02x (%u)\n", p, w, "prh_arg", get_prh_arg(), get_prh_arg()); fprintf(f, "%s%-*s = 0x%08"PRIx64" (%"PRIu64")\n", p, w, "prh_addr", get_prh_addr(), get_prh_addr()); } fprintf(f, "%s%-*s = %d\n", p, w, "addr_encoding", get_addr_encoding()); if (get_instructions().size()>0) { fprintf(f, "%s%-*s = 0x%08zx (%zu) bytes\n", p, w, "instructions", get_instructions().size(), get_instructions().size()); hexdump(f, 0, std::string(p)+"insns at ", get_instructions()); } for (size_t i=0; i<get_fd_entries()->get_entries().size(); i++) { SgAsmElfEHFrameEntryFD *fde = get_fd_entries()->get_entries()[i]; fde->dump(f, p, i); } }
/* * There's no "good way" to differentiate blank vs. non-blank * finals. So, we just scan the code in the CL-init. If * it's sput there, then it's a blank. Lame, agreed, but functional. * */ void get_sput_in_clinit(DexClass* clazz, std::unordered_map<DexField*, bool>& blank_statics) { auto methods = clazz->get_dmethods(); for (auto method : methods) { if (is_clinit(method)) { always_assert_log(is_static(method) && is_constructor(method), "static constructor doesn't have the proper access bits set\n"); auto code = method->get_code(); auto opcodes = code->get_instructions(); for (auto opcode : opcodes) { if (opcode->has_fields() && is_sput(opcode->opcode())) { auto fieldop = static_cast<DexOpcodeField*>(opcode); auto field = resolve_field(fieldop->field(), FieldSearch::Static); if (field == nullptr || !field->is_concrete()) continue; if (field->get_class() != clazz->get_type()) continue; blank_statics[field] = true; } } } } }
//The main part of the game running problems and movement etc. void run_main_game(roomGrid *room_grid, progress *puzzle, Chicken *hen) { char *instructions_list[NUM_INSTRUCTIONS]; get_instructions(instructions_list); Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, AUDIO_S16SYS, MUSIC_CONST_ONE, MUSIC_CONST_TWO); room_grid -> mus = Mix_LoadWAV("20141124b.wav"); //Prints the opening scene. print_instruction(room_grid, instructions_list, 0, 10); draw(room_grid, puzzle, instructions_list, hen); atexit(SDL_Quit); //Mix_HaltMusic(); //Mix_FreeChunk(mus); //Mix_CloseAudio(); // Mix_Quit(); IMG_Quit(); SDL_Quit(); }
/** Unparse one Common Information Entry (CIE) without unparsing the Frame Description Entries (FDE) to which it points. The * initial length fields are not included in the result string. */ std::string SgAsmElfEHFrameEntryCI::unparse(const SgAsmElfEHFrameSection *ehframe) const { SgAsmElfFileHeader *fhdr = ehframe->get_elf_header(); ROSE_ASSERT(fhdr!=NULL); /* Allocate worst-case size for results */ size_t worst_size = (4+ 1+ get_augmentation_string().size()+1+ 10+ 10+ 10+ get_augmentation_data_length()+ get_instructions().size()+ fhdr->get_word_size()); unsigned char *buf = new unsigned char[worst_size]; rose_addr_t at = 0; uint32_t u32_disk; unsigned char u8_disk; /* CIE back offset (always zero) */ u32_disk=0; memcpy(buf+at, &u32_disk, 4); at+=4; /* Version */ u8_disk = get_version(); memcpy(buf+at, &u8_disk, 1); at+=1; /* NUL-terminated Augmentation String */ size_t sz = get_augmentation_string().size()+1; memcpy(buf+at, get_augmentation_string().c_str(), sz); at+=sz; /* Alignment factors */ at = ehframe->write_uleb128(buf, at, get_code_alignment_factor()); at = ehframe->write_sleb128(buf, at, get_data_alignment_factor()); /* Augmentation data */ at = ehframe->write_uleb128(buf, at, get_augmentation_data_length()); std::string astr = get_augmentation_string(); if (!astr.empty() && astr[0]=='z') { for (size_t i=1; i<astr.size(); i++) { if ('L'==astr[i]) { u8_disk = get_lsda_encoding(); buf[at++] = u8_disk; } else if ('P'==astr[i]) { u8_disk = get_prh_encoding(); buf[at++] = u8_disk; switch (get_prh_encoding()) { case 0x05: case 0x06: case 0x07: buf[at++] = get_prh_arg(); ByteOrder::host_to_le(get_prh_addr(), &u32_disk); memcpy(buf+at, &u32_disk, 4); at+=4; break; default: /* See parser */ if (++nwarnings<=WARNING_LIMIT) { fprintf(stderr, "%s:%u: warning: unknown PRH encoding (0x%02x)\n", __FILE__, __LINE__, get_prh_encoding()); if (WARNING_LIMIT==nwarnings) fprintf(stderr, " (additional frame warnings will be suppressed)\n"); } break; } } else if ('R'==astr[i]) { u8_disk = get_addr_encoding(); buf[at++] = u8_disk; } else if ('S'==astr[i]) { /* Signal frame; no auxilliary data */ } else { ROSE_ASSERT(!"invalid .eh_frame augmentation string"); abort(); } } } /* Initial instructions */ sz = get_instructions().size(); if (sz>0) { memcpy(buf+at, &(get_instructions()[0]), sz); at += sz; } std::string retval((char*)buf, at); delete[] buf; return retval; }
bool MethodTransform::try_sync() { TRACE(MTRANS, 5, "Syncing %s\n", SHOW(m_method)); auto code = m_method->get_code(); auto& opout = code->get_instructions(); opout.clear(); uint32_t addr = 0; addr_mei_t addr_to_mei; // Step 1, regenerate opcode list for the method, and // and calculate the opcode entries address offsets. TRACE(MTRANS, 5, "Emitting opcodes\n"); for (auto miter = m_fmethod->begin(); miter != m_fmethod->end(); miter++) { MethodItemEntry* mentry = &*miter; TRACE(MTRANS, 5, "Analyzing mentry %p\n", mentry); mentry->addr = addr; if (mentry->type == MFLOW_OPCODE) { if ((mentry->insn->opcode() == FOPCODE_FILLED_ARRAY) && (addr & 1)) { opout.push_back(new DexInstruction(OPCODE_NOP)); ++addr; } addr_to_mei[addr] = mentry; TRACE(MTRANS, 5, "Emitting mentry %p at %08x\n", mentry, addr); opout.push_back(mentry->insn); addr += mentry->insn->size(); } } // Step 2, recalculate branches..., save off multi-branch data. TRACE(MTRANS, 5, "Recalculating branches\n"); std::vector<MethodItemEntry*> multi_branches; std::unordered_map<MethodItemEntry*, std::vector<BranchTarget*>> multis; std::unordered_map<BranchTarget*, uint32_t> multi_targets; std::unordered_map<DexTryItem*, std::vector<MethodItemEntry*>> try_items; for (auto miter = m_fmethod->begin(); miter != m_fmethod->end(); miter++) { MethodItemEntry* mentry = &*miter; if (mentry->type == MFLOW_OPCODE) { auto opcode = mentry->insn->opcode(); if (is_branch(opcode) && is_multi_branch(opcode)) { multi_branches.push_back(mentry); } } if (mentry->type == MFLOW_TARGET) { BranchTarget* bt = mentry->target; if (bt->type == BRANCH_MULTI) { multis[bt->src].push_back(bt); multi_targets[bt] = mentry->addr; // We can't fix the primary switch opcodes address until we emit // the fopcode, which comes later. } else if (bt->type == BRANCH_SIMPLE) { MethodItemEntry* tomutate = bt->src; int32_t branchoffset = mentry->addr - tomutate->addr; if ((tomutate->insn->opcode() == OPCODE_FILL_ARRAY_DATA) && (mentry->addr & 1)) { ++branchoffset; // account for nop spacer } auto encode_result = encode_offset(tomutate->insn, branchoffset); if (!encode_result.success) { auto inst = tomutate->insn; tomutate->insn = new DexInstruction(encode_result.newopcode); delete inst; return false; } } } if (mentry->type == MFLOW_TRY) { try_items[mentry->tentry->tentry].push_back(mentry); } } TRACE(MTRANS, 5, "Emitting multi-branches\n"); // Step 3, generate multi-branch fopcodes for (auto multiopcode : multi_branches) { auto targets = multis[multiopcode]; std::sort(targets.begin(), targets.end(), multi_target_compare_index); if (multi_contains_gaps(targets)) { // Emit sparse. unsigned long count = (targets.size() * 4) + 2; uint16_t sparse_payload[count]; sparse_payload[0] = FOPCODE_SPARSE_SWITCH; sparse_payload[1] = targets.size(); uint32_t* spkeys = (uint32_t*)&sparse_payload[2]; uint32_t* sptargets = (uint32_t*)&sparse_payload[2 + (targets.size() * 2)]; for (auto target : targets) { *spkeys++ = target->index; *sptargets++ = multi_targets[target] - multiopcode->addr; } // Emit align nop if (addr & 1) { DexInstruction* nop = new DexInstruction(0); opout.push_back(nop); addr++; } // Insert the new fopcode... DexInstruction* fop = new DexOpcodeData(sparse_payload, (int) (count - 1)); opout.push_back(fop); // re-write the source opcode with the address of the // fopcode, increment the address of the fopcode. encode_offset(multiopcode->insn, addr - multiopcode->addr); multiopcode->insn->set_opcode(OPCODE_SPARSE_SWITCH); addr += count; } else { // Emit packed. unsigned long count = (targets.size() * 2) + 4; uint16_t packed_payload[count]; packed_payload[0] = FOPCODE_PACKED_SWITCH; packed_payload[1] = targets.size(); uint32_t* psdata = (uint32_t*)&packed_payload[2]; *psdata++ = targets.front()->index; for (auto target : targets) { *psdata++ = multi_targets[target] - multiopcode->addr; } // Emit align nop if (addr & 1) { DexInstruction* nop = new DexInstruction(0); opout.push_back(nop); addr++; } // Insert the new fopcode... DexInstruction* fop = new DexOpcodeData(packed_payload, (int) (count - 1)); opout.push_back(fop); // re-write the source opcode with the address of the // fopcode, increment the address of the fopcode. encode_offset(multiopcode->insn, addr - multiopcode->addr); multiopcode->insn->set_opcode(OPCODE_PACKED_SWITCH); addr += count; } } // Step 4, emit debug opcodes TRACE(MTRANS, 5, "Emitting debug opcodes\n"); auto debugitem = code->get_debug_item(); if (debugitem) { auto& entries = debugitem->get_entries(); entries.clear(); for (auto& mentry : *m_fmethod) { if (mentry.type == MFLOW_DEBUG) { entries.emplace_back(mentry.addr, mentry.dbgop->clone()); } else if (mentry.type == MFLOW_POSITION) { entries.emplace_back(mentry.addr, mentry.pos); } } } // Step 5, try/catch blocks auto& tries = code->get_tries(); tries.clear(); for (auto tryitem : try_items) { DexTryItem* dextry = tryitem.first; auto& tryentries = tryitem.second; sort(tryentries.begin(), tryentries.end(), order_try_entries); dextry->m_catches.clear(); MethodItemEntry* try_start = nullptr; bool suppress = false; for (auto tryentry : tryentries) { switch (tryentry->tentry->type) { case TRY_START: dextry->m_start_addr = tryentry->addr; try_start = tryentry; break; case TRY_END: assert(try_start != nullptr); assert(try_start->addr <= tryentry->addr); dextry->m_insn_count = tryentry->addr - try_start->addr; if (dextry->m_insn_count == 0) { suppress = true; } break; case TRY_CATCH: if (tryentry->tentry->centry == nullptr) { /* Catch all */ dextry->m_catchall = tryentry->addr; } else { dextry->m_catches.push_back( std::make_pair(tryentry->tentry->centry, tryentry->addr)); } break; default: always_assert_log(false, "Invalid try entry type"); } } if (!suppress) { tries.push_back(dextry); } } std::sort(tries.begin(), tries.end(), [](const DexTryItem* a, const DexTryItem* b) { return a->m_start_addr < b->m_start_addr; }); return true; }