예제 #1
0
파일: java.c 프로젝트: pixilla/radare2
static int attributes_walk(RBinJavaObj *bin, struct r_bin_java_attr_t *attr, int sz2, int fields) {
	char buf[0xffff+1]; // that's kinda ugly :)
	int sz3, sz4;
	int j=0,k;
	char *name;

	for (j=0; j<sz2; j++) {
		if (r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)buf, 6) != 6) {
			eprintf ("Cannot read 6 bytes in class file\n");
			return R_FALSE;
		}
		attr->name_idx = R_BIN_JAVA_USHORT(buf,0);
		name = get_cp (bin, attr->name_idx-1)->value;
		// XXX: if name is null.. wat?
		attr->name = strdup (name? name: "");
		name = (get_cp(bin, attr->name_idx-1))->value;//cp_items[R_BIN_JAVA_USHORT(buf,0)-1].value;
		IFDBG printf("   %2d: Name Index: %d (%s)\n", j, attr->name_idx, name);
		// TODO add comment with constant pool index
		sz3 = R_BIN_JAVA_UINT (buf, 2);
		if (fields) {
			attr->type = R_BIN_JAVA_TYPE_FIELD;
			IFDBG printf ("FIELD\n");
		} else if (sz3 > 0){
			attr->length = sz3;
			IFDBG printf ("     Length: %d\n", sz3); //R_BIN_JAVA_UINT(buf, 2));
			if (!name) {
				IFDBG printf ("**ERROR ** Cannot identify attribute name into constant pool\n");
				continue;
			}
			if (!strcmp (name, "Code")) {
				attr->type = R_BIN_JAVA_TYPE_CODE;
				r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)buf, 8);

				attr->info.code.max_stack = R_BIN_JAVA_USHORT(buf, 0);
				IFDBG printf("      Max Stack: %d\n", attr->info.code.max_stack);
				attr->info.code.max_locals = R_BIN_JAVA_USHORT(buf, 2);
				IFDBG printf("      Max Locals: %d\n", attr->info.code.max_locals);
				attr->info.code.code_length = R_BIN_JAVA_UINT(buf, 4);
				IFDBG printf("      Code Length: %d\n", attr->info.code.code_length);
				attr->info.code.code_offset = (ut64)bin->b->cur;
				IFDBG printf("      Code At Offset: 0x%08"PFMT64x"\n", (ut64)attr->info.code.code_offset);

				r_buf_read_at(bin->b, R_BUF_CUR, (ut8*)buf, R_BIN_JAVA_UINT(buf, 4)); // READ CODE
				sz4 = read_short(bin);
				attr->info.code.exception_table_length = sz4;
				IFDBG printf("      Exception table length: %d\n", attr->info.code.exception_table_length);
				for (k=0;k<sz4;k++) {
					r_buf_read_at(bin->b, R_BUF_CUR, (ut8*)buf, 8);
					attr->info.code.start_pc = R_BIN_JAVA_USHORT(buf,0);
					IFDBG printf("       start_pc:   0x%04x\n", attr->info.code.start_pc);
					attr->info.code.end_pc = R_BIN_JAVA_USHORT(buf,2);
					IFDBG printf("       end_pc:     0x%04x\n", attr->info.code.end_pc);
					attr->info.code.handler_pc = R_BIN_JAVA_USHORT(buf,4);
					IFDBG printf("       handler_pc: 0x%04x\n", attr->info.code.handler_pc);
					attr->info.code.catch_type = R_BIN_JAVA_USHORT(buf,6);
					IFDBG printf("       catch_type: %d\n", attr->info.code.catch_type);
				}
				sz4 = (unsigned int)read_short(bin);
				IFDBG printf("      code Attributes_count: %d\n", sz4);

				if (sz4>0) {
					attr->attributes = malloc(1+sz4 * sizeof(struct r_bin_java_attr_t));
					attributes_walk(bin, attr->attributes, sz4, fields);
				}
			} else
			if (!strcmp (name, "LineNumberTable")) {
				attr->type = R_BIN_JAVA_TYPE_LINENUM;
				sz4 = (unsigned int)read_short (bin);
				attr->info.linenum.table_length = sz4;
				IFDBG printf("     Table Length: %d\n", attr->info.linenum.table_length);
eprintf ("line.%d.sym=%s\n", bin->midx, bin->methods[bin->midx].name);
				for (k=0; k<sz4; k++) {
					r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)buf, 4);
					attr->info.linenum.start_pc = R_BIN_JAVA_USHORT (buf, 0);
					//eprintf ("     %2d: start_pc:    0x%04x\n", k, attr->info.linenum.start_pc);
					attr->info.linenum.line_number = R_BIN_JAVA_USHORT (buf, 2);
					//eprintf ("         line_number: %d\n", attr->info.linenum.line_number);
					eprintf ("line.%d.%d.%d=0x%x\n", bin->midx, k,
							attr->info.linenum.line_number,
							attr->info.linenum.start_pc);
				}
			} else
			if (!strcmp (name, "StackMapTable")) {
				r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)buf, 2); // XXX: this is probably wrong
				//printf("     StackMapTable: %d\n", USHORT(buf, 0));
			} else
			if (!strcmp (name, "LocalVariableTable")) {
				int i;
				ut32 lvtl = (ut32)read_short (bin);
eprintf ("local.%d.sym=%s\n", bin->midx, bin->methods[bin->midx].name);
				for (i=0; i<lvtl; i++) {
					int start_pc = start_pc = read_short (bin);
					int length = length = read_short (bin);
					int name_idx = name_idx = read_short (bin);
					int desc_idx = desc_idx = read_short (bin);
					int index = index = read_short (bin);

					const char *name = get_cp (bin, name_idx-1)->value;
					const char *desc = get_cp (bin, desc_idx-1)->value;
eprintf ("local.%d.%d.type=%s\n", bin->midx, i, desc);
eprintf ("local.%d.%d.name=%s\n", bin->midx, i, name);
				}
			} else
			if (!strcmp (name, "ConstantValue")) {
				attr->type = R_BIN_JAVA_TYPE_CONST;
				r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)buf, 2);
	#if 0
				printf("     Name Index: %d\n", R_BIN_JAVA_USHORT(buf, 0)); // %s\n", R_BIN_JAVA_USHORT(buf, 0), cp_items[R_BIN_JAVA_USHORT(buf,0)-1].value);
				printf("     AttributeLength: %d\n", R_BIN_JAVA_UINT(buf, 2));
	#endif
				attr->info.const_value_idx = R_BIN_JAVA_USHORT(buf, 0);
				IFDBG printf ("     ConstValueIndex: %d\n", attr->info.const_value_idx);
			} else {
				eprintf ("** ERROR ** Unknown section '%s'\n", name);
				return R_FALSE;
			}
		}
	}
	return R_TRUE;
}
예제 #2
0
파일: code.c 프로젝트: ReverseLab/radare2
int java_classdump(const char *file, int verbose) {
	RBinJavaClass2 cf2;
	unsigned short sz, sz2;
	int this_class;
	char buf[0x9999];
	int i,j;
	FILE *fd = fopen(file, "rb");

	if (fd == NULL)
		return -1;

	/* start parsing */
	fread (&cf, 10, 1, fd); //sizeof(struct classfile), 1, fd);
	if (memcmp (cf.cafebabe, "\xCA\xFE\xBA\xBE", 4)) {
		eprintf ("java_classdump: Invalid header\n");
		return -1;
	}
	javasm_init ();

	/* show class version information */
	V printf ("Version: 0x%02x%02x 0x%02x%02x\n",
		cf.major[1],cf.major[0], cf.minor[1],cf.minor[0]);

	cf.cp_count = r_num_ntohs(cf.cp_count);
	if (cf.major[0]==cf.major[1] && cf.major[0]==0) {
		eprintf ("Oops. this is a Mach-O\n");
		return 0;
	}
	
	cf.cp_count--;
	V printf ("ConstantPoolCount %d\n", cf.cp_count);
	cp_items = malloc (sizeof (struct cp_item)*(cf.cp_count+1));
	for (i=0;i<cf.cp_count;i++) {
		struct constant_t *c;
		fread (buf, 1, 1, fd);
		c = NULL;
		for (j=0; r_bin_java_constants[j].name; j++) {
			if (r_bin_java_constants[j].tag == buf[0])  {
				c = &r_bin_java_constants[j];
				break;
			}
		}
		if (c == NULL) {
			eprintf ("Invalid tag '%d'\n", buf[0]);
			return 0;
		}
		V eprintf (" %3d %s: ", i+1, c->name);

		/* store constant pool item */
		strcpy (cp_items[i].name, c->name);
		cp_items[i].tag = c->tag;
		cp_items[i].value = NULL; // no string by default
		cp_items[i].off = ftell(fd)-1;

		/* read bytes */
		switch (c->tag) {
		case 1: // utf 8 string
			fread (buf, 2, 1, fd);
			sz = USHORT (buf,0);
			//cp_items[i].len = sz;
			fread(buf, sz, 1, fd);
			buf[sz] = '\0';
			break;
		default:
			fread(buf, c->len, 1, fd);
		}

		memcpy (cp_items[i].bytes, buf, 5);

		/* parse value */
		switch(c->tag) {
		case 1:
			V printf ("%s\n", buf);
			cp_items[i].value = strdup(buf);
			break;
		case 7:
			V printf ("%d\n", USHORT(buf,0));
			break;
		case 8:
			V printf ("string ptr %d\n", USHORT(buf, 0));
			break;
		case 9:
		case 11:
		case 10: // METHOD REF
			V printf("class = %d, ", USHORT(buf,0));
			V printf("name_type = %d\n", USHORT(buf,2));
			break;
		case 12:
			V printf("name = %d, ", USHORT(buf,0));
			V printf("descriptor = %d\n", USHORT(buf,2));
			break;
		default:
			V printf("%d\n", UINT(buf, 40));
		}
	}

	fread (&cf2, sizeof (RBinJavaClass2), 1, fd);
	check_eof(fd);
	V printf("Access flags: 0x%04x\n", cf2.access_flags);
	this_class = r_num_ntohs (cf2.this_class);
	V printf ("This class: %d\n", this_class);
	check_eof (fd);
	//printf("This class: %d (%s)\n", ntohs(cf2.this_class), cp_items[ntohs(cf2.this_class)-1].value); // XXX this is a double pointer !!1
	//printf("Super class: %d (%s)\n", ntohs(cf2.super_class), cp_items[ntohs(cf2.super_class)-1].value);
	sz = read_short (fd);
	V printf ("Interfaces count: %d\n", sz);
	if (sz>0) {
		fread (buf, sz*2, 1, fd);
		sz = read_short (fd);
		for (i=0; i<sz; i++) {
			eprintf ("interfaces: TODO\n");
		}
	}

	sz = read_short(fd);
	V printf("Fields count: %d\n", sz);
	if (sz>0) {
		for (i=0;i<sz;i++) {
			fread(buf, 8, 1, fd);

			V printf("%2d: Access Flags: %d\n", i, USHORT(buf, 0));
			V printf("    Name Index: %d (%s)\n", USHORT(buf, 2), get_cp(USHORT(buf,2)-1)->value);
			V printf("    Descriptor Index: %d\n", USHORT(buf, 4)); //, cp_items[USHORT(buf, 4)-1].value);

			sz2 = USHORT(buf, 6);
			V printf("    field Attributes Count: %d\n", sz2);
			attributes_walk(fd, sz2, 1, verbose);
		}
	}

	sz = read_short(fd);
	V printf("Methods count: %d\n", sz);
	if (sz>0) {
		for (i=0;i<sz;i++) {
			fread(buf, 8, 1, fd);
			check_eof(fd);
			
			V printf("%2d: Access Flags: %d\n", i, USHORT(buf, 0));
			V printf("    Name Index: %d (%s)\n", USHORT(buf, 2), get_cp(USHORT(buf, 2)-1)->value);
			V printf("    Descriptor Index: %d (%s)\n", USHORT(buf, 4), get_cp(USHORT(buf, 4)-1)->value);

			sz2 = USHORT(buf, 6);
			V printf("    method Attributes Count: %d\n", sz2);
			attributes_walk(fd, sz2, 0, verbose);
		}
	}

	fclose(fd);
	return 0;
}
예제 #3
0
파일: java.c 프로젝트: pixilla/radare2
static int javasm_init(RBinJavaObj *bin) {
	unsigned short sz, sz2;
	char buf[0x4096];
	int i, j;

	/* Initialize structs */
	bin->cp_items = NULL;
	bin->fields = NULL;
	bin->methods = NULL;

	/* Initialize cp_null_item */
	cp_null_item.tag = -1;
	strncpy (cp_null_item.name, "(null)", sizeof (cp_null_item.name)-1);
	cp_null_item.value = strdup ("(null)");

	/* start parsing */
	r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)&bin->cf, 10); //sizeof(struct r_bin_java_classfile_t), 1, bin->fd);
	if (memcmp (bin->cf.cafebabe, "\xCA\xFE\xBA\xBE", 4)) {
		eprintf ("javasm_init: Invalid header (%02x %02x %02x %02x)\n",
				bin->cf.cafebabe[0], bin->cf.cafebabe[1],
				bin->cf.cafebabe[2], bin->cf.cafebabe[3]);
		return R_FALSE;
	}

	bin->cf.cp_count = R_BIN_JAVA_SWAPUSHORT (bin->cf.cp_count);
	if (bin->cf.major[0]==bin->cf.major[1] && bin->cf.major[0]==0) {
		fprintf(stderr, "This is a MachO\n");
		return R_FALSE;
	}
	bin->cf.cp_count--;

	IFDBG printf ("ConstantPoolCount %d\n", bin->cf.cp_count);
	bin->cp_items = malloc (sizeof (struct r_bin_java_cp_item_t)*(bin->cf.cp_count+1));
eprintf ("%d\n", bin->cf.cp_count);
	for(i=0;i<bin->cf.cp_count;i++) {
		struct constant_t *c;

		r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)buf, 1);

		c = NULL;
		for (j=0; constants[j].name; j++) {
			if (constants[j].tag == buf[0])  {
				c = &constants[j];
				break;
			}
		}
		if (c == NULL) {
			fprintf (stderr, "Invalid tag '%d' at offset 0x%08"PFMT64x"\n",
				*buf, (ut64)bin->b->cur);
			return R_FALSE;
		}
		IFDBG printf (" %3d %s: ", i+1, c->name);

		/* store constant pool item */
		strncpy (bin->cp_items[i].name, c->name, sizeof (bin->cp_items[i].name)-1);
		bin->cp_items[i].ord = i+1;
		bin->cp_items[i].tag = c->tag;
		bin->cp_items[i].value = NULL; // no string by default
		bin->cp_items[i].off = bin->b->cur-1;

		/* read bytes */
		switch (c->tag) {
		case 1: // Utf8 string
			r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)buf, 2);
			sz = R_BIN_JAVA_USHORT (buf, 0);
			bin->cp_items[i].length = sz;
			bin->cp_items[i].off += 3;
			if (sz<sizeof (buf)) {
				r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)buf, sz);
				buf[sz] = '\0';
			} else {
				eprintf ("Invalid utf8 length %d\n", sz);
				buf[0] = 0;
			}
			break;
		default:
			r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)buf, c->len);
		}

		memcpy (bin->cp_items[i].bytes, buf, 5);

		/* parse value */
		switch (c->tag) {
		case 1:
			// eprintf ("%s\n", buf);
			bin->cp_items[i].value = strdup (buf);
			break;
		case 5:
		case 6:
			i += 2;
			break;
		case 7:
			IFDBG eprintf ("%d\n", R_BIN_JAVA_USHORT (buf,0));
			break;
		case 8:
			IFDBG printf("string ptr %d\n", R_BIN_JAVA_USHORT(buf, 0));
			break;
		case 9:
		case 11:
		case 10: // METHOD REF
			IFDBG printf("class = %d, ", R_BIN_JAVA_USHORT(buf,0));
			IFDBG printf("name_type = %d\n", R_BIN_JAVA_USHORT(buf,2));
			break;
		case 12:
			IFDBG printf("name = %d, ", R_BIN_JAVA_USHORT(buf,0));
			IFDBG printf("descriptor = %d\n", R_BIN_JAVA_USHORT(buf,2));
			break;
		default:
			printf ("%d\n", R_BIN_JAVA_UINT (buf, 40));
		}
	}

	r_buf_read_at (bin->b, R_BUF_CUR, (ut8*)&bin->cf2, sizeof(struct r_bin_java_classfile2_t));
	IFDBG printf ("Access flags: 0x%04x\n", bin->cf2.access_flags);
	bin->cf2.this_class = R_BIN_JAVA_SWAPUSHORT(bin->cf2.this_class);
	IFDBG printf ("This class: %d\n", bin->cf2.this_class);
	//printf("This class: %d (%s)\n", R_BIN_JAVA_SWAPUSHORT(bin->cf2.this_class), bin->cp_items[R_BIN_JAVA_SWAPUSHORT(bin->cf2.this_class)-1].value); // XXX this is a double pointer !!1
	//printf("Super class: %d (%s)\n", R_BIN_JAVA_SWAPUSHORT(bin->cf2.super_class), bin->cp_items[R_BIN_JAVA_SWAPUSHORT(bin->cf2.super_class)-1].value);
	sz = read_short(bin);

	/* TODO: intefaces*/
	IFDBG printf("Interfaces count: %d\n", sz);
	if (sz>0) {
		r_buf_read_at(bin->b, R_BUF_CUR, (ut8*)buf, sz*2);
		sz = read_short(bin);
		for(i=0;i<sz;i++) {
			fprintf(stderr, "Interfaces: TODO\n");
		}
	}

	sz = read_short(bin);
	bin->fields_count = sz;
	IFDBG printf("Fields count: %d\n", sz);
	if (sz>0) {
		bin->fields = malloc (1+sz * sizeof(struct r_bin_java_fm_t));
		for (i=0;i<sz;i++) {
			r_buf_read_at(bin->b, R_BUF_CUR, (ut8*)buf, 8);
			bin->fields[i].flags = R_BIN_JAVA_USHORT(buf, 0);
			IFDBG printf("%2d: Access Flags: %d\n", i, bin->fields[i].flags);
			bin->fields[i].name_idx = R_BIN_JAVA_USHORT(buf, 2);
			bin->fields[i].name = r_str_dup (NULL, (get_cp (bin, R_BIN_JAVA_USHORT(buf,2)-1))->value);
			IFDBG printf("    Name Index: %d (%s)\n", bin->fields[i].name_idx, bin->fields[i].name);
			bin->fields[i].descriptor_idx = R_BIN_JAVA_USHORT(buf, 4);
			bin->fields[i].descriptor = NULL;
			IFDBG printf("    Descriptor Index: %d\n", bin->fields[i].descriptor_idx); //, bin->cp_items[R_BIN_JAVA_USHORT(buf, 4)-1].value);
			sz2 = R_BIN_JAVA_USHORT(buf, 6);
			bin->fields[i].attr_count = sz2;
			IFDBG printf("    field Attributes Count: %d\n", sz2);
			if (sz2 > 0) {
				bin->fields[i].attributes = malloc(1+sz2 * sizeof(struct r_bin_java_attr_t));
				for(j=0;j<sz2;j++)
					attributes_walk(bin, &bin->fields[i].attributes[j], sz2, 1);
			}
		}
	}

	sz = read_short(bin);
	bin->methods_count = sz;
	IFDBG printf("Methods count: %d\n", sz);
	if (sz>0) {
		bin->methods = malloc(sz * sizeof(struct r_bin_java_fm_t));
		for (i=0;i<sz;i++) {
			r_buf_read_at(bin->b, R_BUF_CUR, (ut8*)buf, 8);

			bin->methods[i].flags = R_BIN_JAVA_USHORT(buf, 0);
			IFDBG printf("%2d: Access Flags: %d\n", i, bin->methods[i].flags);
			bin->methods[i].name_idx = R_BIN_JAVA_USHORT(buf, 2);
#if OLD
			bin->methods[i].name = r_str_dup (NULL, (get_cp(bin, R_BIN_JAVA_USHORT(buf, 2)-1))->value);
#else
			bin->methods[i].name = malloc (1024);
// XXX: can null ptr here
			snprintf (bin->methods[i].name, 1023, "%s%s",
				(get_cp (bin, R_BIN_JAVA_USHORT (buf, 2)-1))->value,
				(get_cp (bin, R_BIN_JAVA_USHORT (buf, 2)))->value);
#endif
bin->midx = i;
			IFDBG printf("    Name Index: %d (%s)\n", bin->methods[i].name_idx, bin->methods[i].name);
			bin->methods[i].descriptor_idx = R_BIN_JAVA_USHORT (buf, 4);
			bin->methods[i].descriptor = r_str_dup (NULL, (get_cp(bin, R_BIN_JAVA_USHORT(buf, 4)-1))->value);
			IFDBG printf("    Descriptor Index: %d (%s)\n", bin->methods[i].descriptor_idx, bin->methods[i].descriptor);

			sz2 = R_BIN_JAVA_USHORT(buf, 6);
			bin->methods[i].attr_count = sz2;
			IFDBG printf("    method Attributes Count: %d\n", sz2);
			if (sz2 > 0) {
				bin->methods[i].attributes = malloc (1+sz2 * sizeof (struct r_bin_java_attr_t));
				for (j=0; j<sz2; j++) {
					if (!attributes_walk (bin, &bin->methods[i].attributes[j], sz2, 0))
						return R_FALSE;
				}
			}
		}
	}
	
	return R_TRUE;
}
예제 #4
0
파일: code.c 프로젝트: ReverseLab/radare2
static int attributes_walk(FILE *fd, int sz2, int fields, int verbose) {
	char *name, buf[99999];
	int sz, k, j=0;

	for (j=0;j<sz2;j++) {
		fread(buf, 6, 1, fd);
		name = (get_cp (USHORT(buf,0)-1))->value;
		V printf("   %2d: Name Index: %d (%s)\n", j, USHORT(buf,0), name);
		// TODO add comment with constant pool index
		if (fields) {
			V printf("FIELD\n");
		} else {
			V printf ("     Length: %d\n", UINT (buf, 2));
			if (!name) {
				printf ("**ERROR ** Cannot identify attribute name into constant pool\n");
				continue;
			}
			if (!strcmp (name, "Code")) {
				fread(buf, 8, 1, fd);

				V printf("      Max Stack: %d\n", USHORT(buf, 0));
				V printf("      Max Locals: %d\n", USHORT(buf, 2));
				V printf("      Code Length: %d\n", UINT(buf, 4));
				V printf("      Code At Offset: 0x%08"PFMT64x"\n", (ut64)ftell(fd));

				fread(buf, UINT(buf, 4), 1, fd); // READ CODE
				sz = read_short(fd);
				V printf("      Exception table length: %d\n", sz);
				for (k=0;k<sz;k++) {
					fread(buf, 8, 1, fd);
					V printf("       start_pc:   0x%04x\n", USHORT(buf,0));
					V printf("       end_pc:     0x%04x\n", USHORT(buf,2));
					V printf("       handler_pc: 0x%04x\n", USHORT(buf,4));
					V printf("       catch_type: %d\n", USHORT(buf,6));
				}
				sz = (int)read_short(fd);
				V printf("      code Attributes_count: %d\n", sz);

				if (sz>0)
					attributes_walk(fd, sz, fields, verbose);
			} else
			if (!strcmp(name, "LineNumberTable")) {
				sz = (int)read_short(fd);
				V printf("     Table Length: %d\n", sz);
				for(k=0;k<sz;k++) {
					fread(buf, 4, 1, fd);
					V printf("     %2d: start_pc:    0x%04x\n", k, USHORT(buf, 0));
					V printf("         line_number: %d\n", USHORT(buf, 2));
				}
			} else
			if (!strcmp(name, "StackMapTable")) {
				fread (buf, 2, 1, fd);
				V printf("     StackMapTable: %d\n", USHORT(buf, 0));
			} else
			if (!strcmp (name, "LocalVariableTable")) {
				int i;
				ut32 lvtl = (ut32)read_short (fd);
				for (i=0; i<lvtl; i++) {
					int start_pc = start_pc = read_short (fd);
					int length = length = read_short (fd);
					int name_idx = name_idx = read_short (fd);
					int desc_idx = desc_idx = read_short (fd);
					int index = index = read_short (fd);
				}
			} else
			if (!strcmp(name, "ConstantValue")) {
				fread(buf, 2, 1, fd);
	#if 0
				printf("     Name Index: %d\n", USHORT(buf, 0)); // %s\n", USHORT(buf, 0), cp_items[USHORT(buf,0)-1].value);
				printf("     AttributeLength: %d\n", UINT(buf, 2));
	#endif
				V printf("     ConstValueIndex: %d\n", USHORT(buf, 0));
			} else {
				fprintf (stderr, "** ERROR ** Unknown section '%s'\n", name);
				return 1;
			}
		}
	}
	return 0;
}