예제 #1
0
파일: uprobes.c 프로젝트: acton393/linux
/*
 * NOTE:
 * Expect the breakpoint instruction to be the smallest size instruction for
 * the architecture. If an arch has variable length instruction and the
 * breakpoint instruction is not of the smallest length instruction
 * supported by that architecture then we need to modify is_trap_at_addr and
 * uprobe_write_opcode accordingly. This would never be a problem for archs
 * that have fixed length instructions.
 *
 * uprobe_write_opcode - write the opcode at a given virtual address.
 * @mm: the probed process address space.
 * @vaddr: the virtual address to store the opcode.
 * @opcode: opcode to be written at @vaddr.
 *
 * Called with mm->mmap_sem held for write.
 * Return 0 (success) or a negative errno.
 */
int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr,
			uprobe_opcode_t opcode)
{
	struct page *old_page, *new_page;
	struct vm_area_struct *vma;
	int ret;

retry:
	/* Read the page with vaddr into memory */
	ret = get_user_pages_remote(NULL, mm, vaddr, 1, FOLL_FORCE, &old_page,
			&vma);
	if (ret <= 0)
		return ret;

	ret = verify_opcode(old_page, vaddr, &opcode);
	if (ret <= 0)
		goto put_old;

	ret = anon_vma_prepare(vma);
	if (ret)
		goto put_old;

	ret = -ENOMEM;
	new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
	if (!new_page)
		goto put_old;

	__SetPageUptodate(new_page);
	copy_highpage(new_page, old_page);
	copy_to_page(new_page, vaddr, &opcode, UPROBE_SWBP_INSN_SIZE);

	ret = __replace_page(vma, vaddr, old_page, new_page);
	put_page(new_page);
put_old:
	put_page(old_page);

	if (unlikely(ret == -EAGAIN))
		goto retry;
	return ret;
}
예제 #2
0
파일: masm.c 프로젝트: likeyiyy/Mirrors
static int masm_main_loop(char * obj_file,char * src_file)
{
    FILE * obj_fp, *src_fp;
    char buf[BUFSIZ] = {0};
    int     length;
    char *  p, * q;
    src_fp = obj_fp = NULL;
    uint32_t counter = 0;
    uint32_t lines   = 0;
    hash_table * label_hash = hash_create(512);

    char op_name[128];
    char label[128];
    char rd[6];
    char rs[6];
    char rt[6];
    char imm[20];
    int32_t rd_num,rs_num,rt_num,imm_num;

    if((src_fp = fopen(src_file,"r")) == NULL)
    {
        printf("Can not open %s:%s\n",src_file,strerror(errno));
    }
    if((obj_fp = fopen(obj_file,"w+")) == NULL)
    {
        printf("Can not open %s:%s\n",obj_file,strerror(errno));
    }
    int total_lines = get_file_lines(src_fp);
    uint32_t * instruction = calloc(1,total_lines * sizeof(uint32_t));
    var_t    * var = calloc(1,total_lines * sizeof(var_t));
    int     var_count = 0;
    fseek(src_fp,0L,SEEK_SET);
    while(1)
    {
        fgets(buf,BUFSIZ,src_fp);
        if(feof(src_fp))
        {
            break;
        }
        lines++;
        length = strlen(buf);
        p     = buf;
        
        //skip whitespace
        while(length > 0 &&isspace(p[0]))
        {
            length--;
            p++;
        }
        //printf("length=%d\t%s",length,buf+i);
        if(p[0] == ';' || p[0] == '\0')
        {
            continue;
        }
        q = get_first_token(p);
        strncpy(op_name, p , q-p);
        op_name[q-p] = '\0';
        if(line_has_label(p))
        {
            /* it is label */
            label_t l;
            l.name = op_name;
            l.real_line = lines;
            l.line = counter;
            hash_add_item(&label_hash,str2hash(op_name),&l);
            p = skip_label_wthie(q);
            /* 获得字符串 */
            q = get_opcode_token(p);
            strncpy(op_name, p , q-p);
            op_name[q-p] = '\0';
            //printf("%s",op_name);
        }

        /* p now a opcode start q-p is opecode */
        int op_index = verify_opcode(op_name,lines);
        q = skip_wthie(q);
        p = q;
        /* now at rd */

        switch(op_index)
        {
#if 1
        	case ADD:
        	case SUB:
        	case MUL:
        	case DIV:
        	case MOD:
        	case AND:
        	case OR:
        	case NOT:
        	case XOR:
        	case LWORD:
        	case SWORD:
                /* 获得字符串 */
            q = get_reg_token(p);
            strncpy(rd, p , q-p);
            rd[q-p] = '\0';
            q = skip_reg_wthie(q);
            p = q;

            q = get_reg_token(p);
            strncpy(rs, p , q-p);
            rs[q-p] = '\0';
            q = skip_reg_wthie(q);
            p = q;

            q = get_reg_token(p);
            strncpy(rt, p , q-p);
            rt[q-p] = '\0';
            rd_num = get_reg_index(rd,lines);
            rs_num = get_reg_index(rs,lines);
            rt_num = get_reg_index(rt,lines);
            instruction[counter] = (op_index << 26) | (rd_num << 21) | (rs_num << 16)| (rt_num << 11);
            break;
            ///C语言中的左移就是逻辑左移,而右移,
            ///对于无符号数来说就是逻辑右移,
            ///对有符号来说就是算术右移
            ///想要实现符号左移,比较麻烦一点,首先保存最高位,然后左移之后补上最高位。
        	case SLL:
        	case SLR:
            case SAL:
        	case SAR:
        	case ADDI:
        	case ANDI:  ///这里的立即数是0扩展的。
        	case ORI:
        	case XORI:
        	case LUI: ///哦,载入高16位数啊,靠,那么低位怎么载入呢?用ori
            q = get_reg_token(p);
            strncpy(rd, p , q-p);
            rd[q-p] = '\0';
            q = skip_reg_wthie(q);
            p = q;

            q = get_reg_token(p);
            strncpy(rs, p , q-p);
            rs[q-p] = '\0';
            q = skip_reg_wthie(q);
            p = q;

            q = get_reg_token(p);
            strncpy(imm, p , q-p);
            imm[q-p] = '\0';
            rd_num = get_reg_index(rd,lines);
            rs_num = get_reg_index(rs,lines);
            imm_num = atoi(imm);
            if(imm_num > 32767 || imm_num < -32768)
            {
                printf("________\n");
                printf("[ERROR 6] line: %d imm num is too lager or too smaller\n",lines);
            }
            instruction[counter] = (op_index << 26) | (rd_num << 21) | (rs_num << 16)| (imm_num & 0x0000ffff);

            break;
        	case LESS:
        	case GREAT:
            case LESSE:
        	case GREATE:
        	case LESSU:
        	case GREATU:
            case LESSEU:
        	case GREATEU:
        	case EQUAL:
        	case UEQUAL:
            q = get_reg_token(p);
            strncpy(rd, p , q-p);
            rd[q-p] = '\0';
            q = skip_reg_wthie(q);
            p = q;

            q = get_reg_token(p);
            strncpy(rs, p , q-p);
            rs[q-p] = '\0';
            q = skip_reg_wthie(q);
            p = q;

            q = get_reg_token(p);
            strncpy(label, p , q-p);
            label[q-p] = '\0';
            rd_num = get_reg_index(rd,lines);
            rs_num = get_reg_index(rs,lines);
            var[var_count].name = malloc(strlen(label) + 1);
            strcpy(var[var_count].name, label);
            var[var_count].line = counter;
            var_count++;
            instruction[counter] = (op_index << 26) | (rd_num << 21) | (rs_num << 16) | 0x0;
        	break;
        	case JMP:
            q = get_reg_token(p);
            strncpy(label, p , q-p);
            label[q-p] = '\0';
            var[var_count].name = malloc(strlen(label) + 1);
            strcpy(var[var_count].name, label);
            var[var_count].line = counter;
            var_count++;
            instruction[counter] = (op_index << 26);
            break;
            /* 存储指令 */
        	case MOV:
            q = get_reg_token(p);
            strncpy(rd, p , q-p);
            rd[q-p] = '\0';
            q = skip_reg_wthie(q);
            p = q;

            q = get_reg_token(p);
            strncpy(rs, p , q-p);
            rs[q-p] = '\0';
            rd_num = get_reg_index(rd,lines);
            rs_num = get_reg_index(rs,lines);
            instruction[counter] = (op_index << 26) | (rd_num << 21) | (rs_num << 16) | 0x0;
                break;
            default:
                break;
            #endif
        }
        counter++;
    }

    /* 第二趟汇编 */
    struct blist * head;
    for(int i = 0; i < var_count; i++)
    {
        if((head = hash_lookup_item(label_hash,str2hash(var[i].name),&var[i])) != NULL)
        {
            label_t * node = head->item;
            int imm_2 = node->line - var[i].line;
            if((instruction[var[i].line] >> 26) == JMP)
            {
                if(imm_2 > 33554431 || imm_2 < -33554432)
                {
                    printf("[ERROR 7] line: %d imm num is too lager or too smaller\n",lines);
                }
                instruction[var[i].line] |= imm_2 & 0x03ffffff;
            }
            else
            {
                if(imm_2 > 32767 || imm_2 < -32768)
                {
                    printf("[ERROR 6] line: %d imm num is too lager or too smaller\n",lines);
                }
                instruction[var[i].line] |= imm_2 & 0x0000ffff;
            }
        }