示例#1
0
void
CGIFImage::
readHeader(CFile *file, CGenImage *, CGIFImageHeader *header)
{
    uchar byte1;
    uchar byte2;

    file->read((uchar *) header->signature, 3);
    file->read((uchar *) header->version  , 3);

    file->read(&byte1, 1);
    file->read(&byte2, 1);

    header->width = (byte2 << 8) | byte1;

    file->read(&byte1, 1);
    file->read(&byte2, 1);

    header->height = (byte2 << 8) | byte1;

    file->read(&header->flags     , 1);
    file->read(&header->background, 1);
    file->read(&header->aspect    , 1);

    header->color_bits         = (header->flags     ) & 0x07;
    header->colors_sorted      = (header->flags >> 3) & 0x01;
    header->max_color_bits     = (header->flags >> 4) & 0x07;
    header->global_color_table = (header->flags >> 7) & 0x01;

    if (CGIFImage::getDebug()) {
        std::cerr << "Signature     " << header->signature[0] << header->signature[1] <<
                  header->signature[2] << std::endl;
        std::cerr << "Version       " << header->version[0] << header->version[1] <<
                  header->version[2] << std::endl;
        std::cerr << "Width         " << header->width << std::endl;
        std::cerr << "Height        " << header->height << std::endl;
        std::cerr << "Num Colors    " << (1 << (header->color_bits + 1)) << std::endl;
        std::cerr << "Colors Sorted " << (int) header->colors_sorted << std::endl;
        std::cerr << "Max Colors    " << 1 << (header->max_color_bits + 1) << std::endl;
        std::cerr << "Global Colors " << (int) header->global_color_table << std::endl;
        std::cerr << "Background    " << (int) header->background << std::endl;
        std::cerr << "Aspect        " << (int) header->aspect << std::endl;
    }

    if (strncmp(header->signature, "GIF", 3) != 0)
        CTHROW("Not a GIF File");

    int type = 0;

    if      (strncmp(header->version, "87a", 3) == 0)
        type = GIF87a;
    else if (strncmp(header->version, "89a", 3) == 0)
        type = GIF89a;

    if (type != GIF87a && type != GIF89a)
        CTHROW("Invalid GIF Version");
}
const PSViewName &
PSViewDictionaryToken::
getName()
{
  CTHROW("No name for token");

  return psview_->getNameMgr()->getName("");
}
示例#3
0
const PSViewName &
PSViewBooleanToken::
getName()
{
  CTHROW("No name for token");

  return psview_->getNameMgr()->getName("");
}
示例#4
0
CGIFAnim *
CGIFImage::
createAnim(CFile *file, CGenImage *proto)
{
    CGIFAnim *image_anim = new CGIFAnim;

    //------

    file->rewind();

    //------

    CGIFImageData *gif_data = new CGIFImageData;

    gif_data->header = new CGIFImageHeader;

    gif_data->global_colors     = NULL;
    gif_data->num_global_colors = 0;
    gif_data->local_colors      = NULL;
    gif_data->num_local_colors  = 0;

    //------

    try {
        memset(&compress_data, 0, sizeof(CGIFImageCompressData));

        CGenImage *image = NULL;

        readHeader(file, image, gif_data->header);

        //------

        readGlobalColors(file, gif_data);

        //------

        readAnimData(file, proto, image_anim, gif_data);
    }
    catch (...) {
        CTHROW("Failed to read GIF file");
    }

    //------

    if (gif_data != NULL) {
        delete gif_data->header;

        delete [] gif_data->global_colors;
        delete [] gif_data->local_colors;
    }

    delete gif_data;

    //------

    return image_anim;
}
示例#5
0
bool
CGIFImage::
readHeader(CFile *file, CGenImage *image)
{
    file->rewind();

    try {
        CGIFImageHeader header;

        readHeader(file, image, &header);

        //------

        image->setType(CFILE_TYPE_IMAGE_GIF);

        image->setSize(header.width, header.height);
    }
    catch (...) {
        CTHROW("Failed to read GIF file");
        return false;
    }

    return true;
}
示例#6
0
void
CGIFImage::
readAnimData(CFile *file, CGenImage *proto, CGIFAnim *image_anim, CGIFImageData *gif_data)
{
    int  inum              = 0;
    int  delay             = 0;
    bool transparent       = false;
    uint transparent_color = 0;
    int  dispose           = 0;
    int  user_input        = 0;

    uint file_size = file->getSize();

    while (true) {
        uchar id;

        try {
            if (! file->read(&id, 1))
                break;
        }
        catch (...) {
            break;
        }

        if      (id == IMAGE_ID) {
            ++inum;

            if (CGIFImage::getDebug())
                std::cerr << "Image Id" << std::endl;

            CGIFImageImageHeader *image_header = new CGIFImageImageHeader;

            try {
                uchar byte1;
                uchar byte2;

                file->read(&byte1, 1);
                file->read(&byte2, 1);

                image_header->left = (byte2 << 8) | byte1;

                file->read(&byte1, 1);
                file->read(&byte2, 1);

                image_header->top = (byte2 << 8) | byte1;

                file->read(&byte1, 1);
                file->read(&byte2, 1);

                image_header->width = (byte2 << 8) | byte1;

                file->read(&byte1, 1);
                file->read(&byte2, 1);

                image_header->height = (byte2 << 8) | byte1;

                file->read(&image_header->flags, 1);

                image_header->local_color_table = (image_header->flags >> 7) & 0x01;
                image_header->interlaced        = (image_header->flags >> 6) & 0x01;
                image_header->colors_sorted     = (image_header->flags >> 5) & 0x01;
                image_header->color_bits        = (image_header->flags     ) & 0x07;

                if (CGIFImage::getDebug()) {
                    std::cerr << "Left          " << image_header->left << std::endl;
                    std::cerr << "Top           " << image_header->top << std::endl;
                    std::cerr << "Width         " << image_header->width << std::endl;
                    std::cerr << "Height        " << image_header->height << std::endl;
                    std::cerr << "Local Colors  " << image_header->local_color_table << std::endl;
                    std::cerr << "Interlaced    " << image_header->interlaced << std::endl;
                    std::cerr << "Colors Sorted " << image_header->colors_sorted << std::endl;
                    std::cerr << "Num Colors    " << (1 << (image_header->color_bits + 1)) << std::endl;
                }

                if (image_header->local_color_table &&
                        image_header->color_bits > 0) {
                    gif_data->num_local_colors = 1 << (image_header->color_bits + 1);

                    gif_data->local_colors = new CGIFImageColorTable [gif_data->num_local_colors];

                    for (int i = 0; i < gif_data->num_local_colors; ++i)
                        file->read((uchar *) &gif_data->local_colors[i], 3);

                    if (CGIFImage::getDebug()) {
                        for (int i = 0; i < gif_data->num_local_colors; ++i)
                            std::cerr << gif_data->local_colors[i].r << " " <<
                                      gif_data->local_colors[i].g << " " <<
                                      gif_data->local_colors[i].b << std::endl;
                    }
                }

                file->read(&compress_data.code_size, 1);

                compress_data.clear_code = 1 << compress_data.code_size;
                compress_data.eof_code   = compress_data.clear_code + 1;
                compress_data.free_code  = compress_data.clear_code + 2;

                ++compress_data.code_size;

                compress_data.init_code_size = compress_data.code_size;

                compress_data.max_code  = 1 << compress_data.code_size;
                compress_data.code_mask = compress_data.max_code - 1;

                uint num_image_bytes = image_header->width*image_header->height;

                uchar *data = new uchar [file_size];

                uchar size;

                file->read(&size, 1);

                uint num_bytes_read = 0;

                while (size > 0) {
                    while (size--) {
                        file->read(&data[num_bytes_read], 1);

                        ++num_bytes_read;
                    }

                    file->read(&size, 1);
                }

                if (num_bytes_read < file_size)
                    memset(&data[num_bytes_read], 0, file_size - num_bytes_read);

                //------

                uchar *raw_data = new uchar [num_image_bytes];

                decompressData(data, num_bytes_read, raw_data, num_image_bytes);

                delete [] data;

                if (image_header->interlaced)
                    deInterlace(raw_data, image_header);

                //------

                CGenImage *image = proto->dup();

                image->setType(CFILE_TYPE_IMAGE_GIF);

                image->setColormap(true);

                image->setDataSize(image_header->width, image_header->height);

                int bottom = gif_data->header->height - image_header->height - image_header->top;
                int right  = gif_data->header->width  - image_header->width  - image_header->left;

                //image->setBorder(image_header->left, bottom, right, image_header->top);
                if (bottom != 0 || right != 0) std::cerr << "Unhandled border" << std::endl;

                if (gif_data->num_local_colors > 0) {
                    for (int i = 0; i < gif_data->num_local_colors; ++i) {
                        CRGBA rgba;

                        rgba.setRGBAI(gif_data->local_colors[i].r,
                                      gif_data->local_colors[i].g,
                                      gif_data->local_colors[i].b);

                        image->addColor(rgba);
                    }
                }
                else {
                    for (int i = 0; i < gif_data->num_global_colors; ++i) {
                        CRGBA rgba;

                        rgba.setRGBAI(gif_data->global_colors[i].r,
                                      gif_data->global_colors[i].g,
                                      gif_data->global_colors[i].b);

                        image->addColor(rgba);
                    }

                    //image->setBackground(image->getColor(gif_data->header->background));
                }

                //------

                if (transparent)
                    image->setTransparentColor(transparent_color);

                //------

                for (int y = 0, k = 0; y < image_header->height; ++y)
                    for (int x = 0; x < image_header->width; ++x, ++k)
                        image->setColorIndex(x, y, raw_data[k]);

                delete [] raw_data;

                //------

                CGIFFrame *frame = new CGIFFrame(image);

                frame->setDelay(delay);
                frame->setDispose(dispose);
                frame->setUserInput(user_input);

                image_anim->add(frame);

                //------

                delay             = 0;
                transparent       = false;
                transparent_color = 0;
                dispose           = 0;
                user_input        = 0;

                //------

                delete image_header;

                image_header = NULL;
            }
            catch (...) {
                delete image_header;

                CTHROW("Failed to read GIF file");
            }
        }
        else if (id == CONTROL_ID) {
示例#7
0
static void
inject_memory(void)
{
	struct mem_region * stack_r = NULL;

	SYS_TRACE("nr_regions=%d\n", cf->nr_regions);

	/* for each mem region in ckpt file */
	for (int i = 0; i < cf->nr_regions; i++) {

		struct mem_region * r = cf->regions[i];

		SYS_TRACE("range %d: 0x%x--0x%x (0x%x:0x%x): %s\n",
				i, r->start, r->end, r->prot, r->offset, r->fn);

		/* find the region already mapped */
		struct proc_entry e;
		bool_t res;
		uint32_t start, end;
		start = r->start;
		end = r->end;
		do {
			res = proc_find_in_range(&e, child_pid, start, end);

			if (res) {
				start = e.end;
				SYS_TRACE("\talready mapped in target: 0x%x--0x%x (0x%x:0x%x): %s\n",
						e.start, e.end, e.prot, e.offset, e.fn);


				/* check if 2 maps are same */
				if ((e.start != r->start) ||
						(e.end != r->end) ||
						(e.prot != r->prot) ||
						(strcmp(e.fn, r->fn) != 0))
				{
					/* different */
					/* special treat [heap] and [stack] */
					if (strcmp(e.fn, "[heap]") == 0) {
						/* heap size is different */
						/* that shouldn't happen, we restore heap address before
						 * calling this function*/
						THROW(EXCEPTION_FATAL, "heap address inconsistent");
					} else if (strcmp(e.fn, "[stack]") == 0) {
						if (strcmp(r->fn, "[stack]") != 0) {
							/* that shouldn't happen... */
							THROW(EXCEPTION_FATAL, "stack inconsistent");
						}
						/* stack can auto expand */
					} else if (strcmp(e.fn, "[vdso]") == 0) {
						THROW(EXCEPTION_FATAL, "vdso inconsistent");
					} else {
						/* unmap the already mapped file */
						/* first, check eip */
						struct user_regs_struct regs = ptrace_peekuser();
						if ((regs.eip >= e.start) && (regs.eip < e.end)) {
							/* target ckpt is special: it unmap itself... */
							/* currently we don't support it */
							THROW(EXCEPTION_FATAL, "eip (0x%x) inconsistent",
									(uint32_t)regs.eip);
						}

						/* now we can safely unmap that file or memregion */
						int err;
						SYS_TRACE("\tunmap 0x%x--0x%x\n", e.start, e.end);
						err = ptrace_syscall(munmap, 2, e.start, e.end - e.start);
						if (err < 0)
							THROW(EXCEPTION_FATAL, "unmap memrigon 0x%x--0x%x failed: %d",
									e.start, e.end, err);
					}
				}
			} else {
				start = r->end;
			}
		} while (start < end);


		/* now the region has been cleaned up, there may be 2 situations:
		 * 1. the desired region is empty;
		 * 2. the desired region is mapped, but the same as ckpt.
		 * here we use procutils to check it again. */
		res = proc_find_in_range(&e, child_pid, r->start, r->end);
		if (res) {
			SYS_TRACE("\tdesired region is mapped\n");
			if ((e.start != r->start) ||
					(e.end != r->end) ||
					(e.prot != r->prot) ||
					(strcmp(e.fn, r->fn) != 0))
			{
				/* if the lower end of stack inconsistent, don't care.
				 * stack is auto expandable. */
				/* NOT(e.fn same as r->fn and e.fn is "[stack]") */
				if (!(!strcmp(e.fn, r->fn) && !strncmp(e.fn, "[stack]", 7))) {
					INJ_FATAL("this region is not cleaned up:\n");
					INJ_FATAL("\tstart : 0x%x 0x%x\n", e.start, r->start);
					INJ_FATAL("\tend   : 0x%x 0x%x\n", e.end, r->end);
					INJ_FATAL("\tprot  : 0x%x 0x%x\n", e.prot, r->prot);
					INJ_FATAL("\tfn:   : \"%s\" \"%s\"\n", e.fn, r->fn);
					THROW(EXCEPTION_FATAL, "Shouldn't happed...\n");
				}
			}
		} else {
			SYS_TRACE("\tdesired region is unmapped\n");
			/* from the ckpt, find the file and do the map */
			uint32_t map_addr = r->start;
			uint32_t size = r->end - r->start;
			uint32_t prot = r->prot;
			uint32_t flags = MAP_FIXED | MAP_EXECUTABLE | MAP_PRIVATE;
			if ((r->fn_len <= 1) || (r->fn[0] == '\0')) {
				/* this is not a file map */
				uint32_t ret_addr;
				flags |= MAP_ANONYMOUS;
				SYS_TRACE("\tdo the anonymouse map\n");
				ret_addr = ptrace_syscall(mmap2, 6,
						map_addr, size, prot,
						flags, 0, 0);
				CTHROW(map_addr == ret_addr, "mmap2 failed, return 0x%x, not 0x%x",
						ret_addr, map_addr);
			} else {
				/* this is a file map */
				uint32_t fn_pos;
				/* push the filename */
				fn_pos = ptrace_push(r->fn, strlen(r->fn) + 1, TRUE);

				int fd = ptrace_syscall(open, 3, fn_pos, O_RDONLY, 0);
				CTHROW(fd >= 0, "open file %s failed: %d", r->fn, fd);

				SYS_TRACE("\tdo the map\n");
				uint32_t off = r->offset;
				uint32_t ret_addr = ptrace_syscall(mmap2, 6,
						map_addr, size, prot,
						flags, fd, off >> PAGE_SHIFT);
				CTHROW(ret_addr == map_addr, "mmap2 file %s failed: return 0x%x",
						r->fn, ret_addr);

				ptrace_syscall(close, 1, fd);
			}
		}

		/* now the memory region has been built up, we then poke
		 * memory into it */
		/* don't update stack here. although in most case the stack
		 * is the last region we meet, there are some special situations.
		 * for example in compat memlayout. the stack may be polluted by
		 * pervious ptrace_push operation. */
		if (strcmp(r->fn, "[stack]") == 0)
			stack_r = r;
		else if (strcmp(r->fn, "[vdso]") != 0)	/* chkp don't contain vdso */
			ptrace_updmem(r->f_pos + cf->ckpt_img,
					r->start,
					r->end - r->start);
	}


	CTHROW(stack_r != NULL, "no \"[stack]\" found");
	/* we poke stack at last */
	ptrace_updmem(stack_r->f_pos + cf->ckpt_img,
			stack_r->start,
			stack_r->end - stack_r->start);
}
示例#8
0
static void
gdbloader_main(const char * target_fn)
{
	/* check: target_fn should be same as argv[0] */
	if (strcmp(target_fn, cf->cmdline[0]) != 0) {
		SYS_FATAL("target should be %s, not %s\n", cf->cmdline[0], target_fn);
		THROW(EXCEPTION_FATAL, "cmdline error");
	}

	/* execve child */
	child_pid = ptrace_execve(target_fn, cf->cmdline, cf->environ);

	/* inject memory */
	/* before we inject memory, we need to restore heap */
	uint32_t heap_end;
	heap_end = ptrace_syscall(brk, 1, cf->state->brk);
	CTHROW(heap_end == cf->state->brk, "restore heap failed: %d",
			heap_end);
	SYS_TRACE("restore heap to 0x%x\n", heap_end);

	inject_memory();

	/* then, we retrive the inject so file, enter from
	 * __debug_entry. we need to push:
	 * nothing.
	 * process can retrive all from state vector.
	 * and we cannot use stack now
	 * */
	/* NOTICE: the state_vector should be saved in the ckpt memory,
	 * we needn't restore them in ptrace process. let the inject so
	 * to do it. */

	/* from the opts get the so-file bias */
	uint32_t inj_bias = opts->inj_bias;
	/* use procutils to get the file */
	struct proc_entry e;
	e.start = inj_bias;
	e.bits = PE_START; 
	proc_fill_entry(&e, child_pid);
	SYS_TRACE("inject so is %s\n", e.fn);

	/* use elfutils to retrive the symbol */
	void * img = load_file(e.fn);
	struct elf_handler * inj_so = elf_init(img, inj_bias);

	uintptr_t debug_entry = elf_get_symbol_address(inj_so,
			opts->entry);
	SYS_TRACE("symbol %s at 0x%x\n", opts->entry, debug_entry);

	/* inject the injector opts */
	inject_injopts(inj_so);

	elf_cleanup(inj_so);
	free(img);

	/* we have to restore register here... */
	SYS_FORCE("pid=%d\n", child_pid);
	SYS_FORCE("eip=0x%x\n", cf->state->regs.eip);
	ptrace_pokeuser(cf->state->regs);
	SYS_TRACE("eax=0x%x\n", cf->state->regs.eax);
	SYS_TRACE("ebx=0x%x\n", cf->state->regs.ebx);
	SYS_TRACE("ecx=0x%x\n", cf->state->regs.ecx);
	SYS_TRACE("edx=0x%x\n", cf->state->regs.edx);
	SYS_TRACE("esi=0x%x\n", cf->state->regs.esi);
	SYS_TRACE("edi=0x%x\n", cf->state->regs.edi);
	SYS_TRACE("ebp=0x%x\n", cf->state->regs.ebp);
	SYS_TRACE("esp=0x%x\n", cf->state->regs.esp);
//	SYS_TRACE("gs=0x%x\n", cf->state->regs.gs);
//	SYS_TRACE("es=0x%x\n", cf->state->regs.es);

	/* we push eip at the top of the new stack */
	ptrace_push(&cf->state->regs.eip, sizeof(uint32_t), FALSE);

	/* fix libpthread problem:
	 *
	 * when gdb attaches to target, if it find libpthread, gdb
	 * will try to use libthread_db to retrive thread-local info.
	 * some data, like `errno', is TLS and need those info.
	 *
	 * When gdb does the work, it use ptrace to peek memory from target image.
	 * so gdb will see the original thread info, the tid is different from
	 * current pid, therefore gdb will think there are at least 2 threads and
	 * then it will try to attach to the 'old' one and definitely fail. When this
	 * failure occures, gdb print a warning message.
	 *
	 * We have 2 ways to solve this problem:
	 *
	 * 1. add a syscall into kernel's code, change its pid. it is simple.
	 * 2. change the image when gdb attach.
	 *
	 * We choose the 2nd one because we prefer user space solution.
	 *
	 * */
	uint32_t sym_stack_used = 0, sym_stack_user = 0;
	if (opts->fix_pthread_tid) {
		fix_libpthread(&sym_stack_used, &sym_stack_user);
		SYS_WARNING("sym_stack_used=0x%x, sym_stack_user=0x%x\n",
				sym_stack_used, sym_stack_user);
	}

	/* we push those 2 addresses onto the stack */
	ptrace_push(&sym_stack_used, sizeof(uint32_t), FALSE);
	ptrace_push(&sym_stack_user, sizeof(uint32_t), FALSE);

	/* move eip and detach, let the target process to run */
	ptrace_goto(debug_entry);

	/* detach in main */
	return;
}