예제 #1
0
/** 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;
}
예제 #2
0
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;
}
예제 #3
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();
}
예제 #4
0
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);
}
예제 #5
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;
}
예제 #6
0
/** 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());
}
예제 #7
0
/** 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);
    }
}
예제 #8
0
/*
 * 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;
        }
      }
    }
  }
}
예제 #9
0
//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();
}
예제 #10
0
/** 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;
}
예제 #11
0
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;
}