radare2/shlr/rar/bin.c
pancake 7a0da18725 Add r_bin.rar plugin, per-section arch/bits, fix in S=
Add Sa to set/get per-section arch and bits configuration
Cache io->section and core->io->section to speed up the Sa
Update r_sys_arch*
Add dummy plugin in asm/rar
Fix lines of S=
2012-11-30 01:06:30 +01:00

265 lines
7.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#if 0
entry0 = 0x9a
header:
526172211a0700f94e7300000e0000000000000000a197740000260003010000000000000210415221000000001d000600000000207374646f75742021550ccd10cd981181c8301d6be017692bf82af42bd4afe87a32f4e665e65e6c30e6d124f2003d93c9e689ec9ec9eb30b8e47a731ebd6b61ddeb3430bb76a83030f0304b30003000303e0ff77f30f9dc9da110700adc00000003000000a4
-- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00000000 5261 7221 1a07 00f9 4e73 0000 0e00 0000 Rar!....Ns......
0x00000010 0000 0000 008b 0074 0000 2600 0901 0000 .......t..&.....
0x00000020 0000 0000 0210 4152 2100 0000 001d 0006 ......AR!.......
0x00000030 0000 0000 2073 7464 6f75 7420 2155 0ccd .... stdout !U..
0x00000040 10cd 9811 81c8 301d 6be0 1769 2bf8 2af4 ......0.k..i+.*.
0x00000050 2bd4 afe8 7a32 f4e6 65e6 5e6c 30e6 d124 +...z2..e.^l0..$
0x00000060 f200 3d93 c9e6 89ec 9ec9 eb30 b8e4 7a73 ..=........0..zs
0x00000070 1ebd 6b61 ddeb 3430 bb76 a830 30f0 304b ..ka..40.v.00.0K
0x00000080 3000 3000 303e 0ff7 7f30 f9dc 9da1 1070 0.0.0>...0.....p
0x00000090 0b3c 0000 0003 0000 00aa .<........
-- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00000000 5261 7221 1a07 00f9 4e73 0000 0e00 0000 Rar!....Ns......
0x00000010 0000 0000 00a1 9774 0000 2600 0301 0000 .......t..&..... <--------
0x00000020 0000 0000 0210 4152 2100 0000 001d 0006 ......AR!.......
0x00000030 0000 0000 2073 7464 6f75 7420 2155 0ccd .... stdout !U..
0x00000040 10cd 9811 81c8 301d 6be0 1769 2bf8 2af4 ......0.k..i+.*.
0x00000050 2bd4 afe8 7a32 f4e6 65e6 5e6c 30e6 d124 +...z2..e.^l0..$
0x00000060 f200 3d93 c9e6 89ec 9ec9 eb30 b8e4 7a73 ..=........0..zs
0x00000070 1ebd 6b61 ddeb 3430 bb76 a830 30f0 304b ..ka..40.v.00.0K
0x00000080 3000 3000 303e 0ff7 7f30 f9dc 9da1 1070 0.0.0>...0.....p
0x00000090 0adc 0000 0003 0000 00a4 .......... <--------
0x15 : 0x8b00 -> 0xa197
0x1c : 0x09 -> 0x03
0x90 : 0x0b3c -> 0x0adc
0x99 : 0xaa -> 0xa4
#endif
#include <stdio.h>
#include <stdlib.h>
// crc32
#include "../../libr/hash/crc32.c"
#define eprintf(x,y...) fprintf(stderr,x,##y)
#pragma pack(1)
typedef struct rar_block_t {
unsigned short crc;
unsigned char type;
unsigned short flags;
unsigned short size;
unsigned int add_size;
} __attribute((__packed__)) RarBlock;
typedef struct rar_block_archive_t {
unsigned int pack_size;
unsigned int unpack_size;
unsigned char os; // [msdos,os2,w32,unix,osx,beos]
unsigned int crc;
unsigned int ftime; // datetime (dos format)
unsigned char rarversion; // datetime
unsigned char packmethod;
#if 0
0×30 storing
0×31 fastest compression
0×32 fast compression
0×33 normal compression
0×34 good compression
0×35 best compression
#endif
unsigned short filenamesize;
unsigned int file_attr;
unsigned int high_pack_size;
unsigned int high_unpack_size;
char *filename;
// unsigned long long salt;
// ext_time: present if flags &0x1000) variable size
} __attribute((__packed__)) RarBlockArchive;
typedef struct {
unsigned short crc;
unsigned char type;
unsigned short flags;
unsigned short size;
} hdr_t;
struct filehdr {
hdr_t hdr;
unsigned int PackSize;
unsigned int UnpSize;
unsigned char HostOS;
unsigned int FileCRC;
unsigned int FileTime;
unsigned char UnpVer;
unsigned char Method;
unsigned short NameSize;
union {
unsigned int FileAttr;
unsigned int SubFlags;
};
unsigned char FileName[6];
};
#if 0
HIGH_PACK_SIZE High 4 bytes of 64 bit value of compressed file size.
4 bytes Optional value, presents only if bit 0×100 in HEAD_FLAGS
is set.
HIGH_UNP_SIZE High 4 bytes of 64 bit value of uncompressed file size.
4 bytes Optional value, presents only if bit 0×100 in HEAD_FLAGS
is set.
FILE_NAME File name string of NAME_SIZE bytes size
SALT present if (HEAD_FLAGS & 0×400) != 0
8 bytes
EXT_TIME present if (HEAD_FLAGS & 0×1000) != 0
variable size
#endif
static inline unsigned short shortswap(unsigned short s) {
unsigned char c, *b = (unsigned char *)&s;
c = b[1]; b[1] = b[0]; b[0] = c;
return s;
}
static int israr(unsigned char *b, int sz) {
return (sz>4 && b[0]==0x52 && b[1]==0x61);
}
static int parseBlock(unsigned char *b, int sz) {
#if 0
HEAD_CRC 2 bytes CRC of total block or block part
HEAD_TYPE 1 byte Block type
HEAD_FLAGS 2 bytes Block flags
HEAD_SIZE 2 bytes Block size
ADD_SIZE 4 bytes Optional field added block size
Field ADD_SIZE present only if (HEAD_FLAGS & 0×8000) != 0
#endif
struct filehdr *fhdr;
RarBlockArchive *rba;
RarBlock *rb = (RarBlock*) b;
int i, n, blocksize; // = headsize
// TODO: check size of rarblockstruct and sz
//printf ("Flags : %x\n", rb->flags);
printf ("Type: 0x%x\n", rb->type);
//rb->flags = shortswap (rb->flags);
printf (" Flags: 0x%x\n", rb->flags);
printf (" Size: 0x%x\n", rb->size);
#if 0
// flags
0x4000 : ignored block on old rars
0x8000 : add size
#endif
switch (rb->type) {
case 0x72:
//sequence: 0×52 0×61 0×72 0×21 0x1a 0×07 0×00
eprintf (" + marker block\n");
break;
case 0x73:
eprintf (" + archive header (flags=%x)\n", rb->flags);
rba = b+7;
for (i=0;i<rb->size&&i<sz; i++)
printf ("%02x ", b[7+i]);
printf("\n");
fhdr = b;
printf ("~~~~~(0x%x)~~~~~\n",
fhdr->FileAttr);
printf ("SZ %x %x %x\n", fhdr->PackSize, fhdr->UnpSize , fhdr->FileCRC);
if (fhdr->FileAttr & 0x20000000) {
printf ("IS CODE!\n");
}
//rba->file_attr);
printf ("FILENAME (");
{
int i;
char mark = b[rb->size+31];
for (i=0; b[rb->size+32+i] != mark; i++) {
printf ("%c", b[rb->size+32+i]);
}
}
printf (")\n");
//printf ("FILENAME (%s)\n", b+rb->size +32);//rba->filename);
if (rb->flags & 0x400) {
printf ("~~~~bonus 8\n");
}
if (rb->flags & 0x200) {
printf ("utf8\n");
}
//sequence: 0×52 0×61 0×72 0×21 0x1a 0×07 0×00
#if 0
HEAD_FLAGS Bit flags:
2 bytes
0×0001 Volume attribute (archive volume)
0×0002 Archive comment present
RAR 3.x uses the separate comment block
and does not set this flag.
0×0004 Archive lock attribute
0×0008 Solid attribute (solid archive)
0×0010 New volume naming scheme (volname.partN.rar)
0×0020 Authenticity information present
RAR 3.x does not set this flag.
0×0040 Recovery record present
0×0080 Block headers are encrypted
0×0100 First volume (set only by RAR 3.0 and later)
#endif
break;
case 0x74:
// File header full size including file name and comments
eprintf (" + file header\n");
for(i=0;i<32;i++) {
printf ("%02x ", b[i+38]);
}
printf ("\n");
return 32;
break;
case 0x7a:
eprintf (" + old block is old\n");
break;
default:
eprintf (" + Unknown block type 0x%x\n", rb->type);
break;
}
#if 0
HEAD_TYPE=0×72 marker block
HEAD_TYPE=0×73 archive header
HEAD_TYPE=0×74 file header
HEAD_TYPE=0×75 old style comment header
HEAD_TYPE=0×76 old style authenticity information
HEAD_TYPE=0×77 old style subblock
HEAD_TYPE=0×78 old style recovery record
HEAD_TYPE=0×79 old style authenticity information
HEAD_TYPE=0x7a subblock
#endif
if (rb->flags & 0x8000) {
n = rb->size + rb->add_size;
} else {
n = rb->size;
}
printf (" + SIZE: %d\n", n);
return n;
}
static int parse_rar(unsigned char *b, int sz) {
int idx = 0;
if (!israr (b, sz)) {
eprintf ("File is not rar\n");
return 0;
}
while (idx<sz) {
idx += parseBlock (b+idx, sz-idx);
}
}
int main() {
const char *rarfile = "helloworld.rar";
FILE *fd = fopen (rarfile, "r");
unsigned char buf[4096];
if (fd) {
int size = fread (buf, 1, sizeof (buf), fd);
parse_rar (buf, size);
fclose (fd);
} else eprintf ("Cannot open rarfile\n");
return 0;
}