mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-23 06:25:28 -07:00
commit
97d3ce91fa
746 changed files with 2692 additions and 683940 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -2,3 +2,4 @@
|
||||||
# prevent binary files from CRLF handling, diff and merge:
|
# prevent binary files from CRLF handling, diff and merge:
|
||||||
fpga/fpga.bit -crlf -diff
|
fpga/fpga.bit -crlf -diff
|
||||||
*.bin -crlf -diff
|
*.bin -crlf -diff
|
||||||
|
*.z -crlf -diff
|
||||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -12,10 +12,10 @@
|
||||||
*.map
|
*.map
|
||||||
*.bin
|
*.bin
|
||||||
!client/hardnested/*.bin
|
!client/hardnested/*.bin
|
||||||
!client/hardnested/tables/*.bin
|
|
||||||
*.dll
|
*.dll
|
||||||
*.moc.cpp
|
*.moc.cpp
|
||||||
*.z
|
*.z
|
||||||
|
!client/hardnested/tables/*.z
|
||||||
usb_cmd.lua
|
usb_cmd.lua
|
||||||
version.c
|
version.c
|
||||||
client/ui/ui_overlays.h
|
client/ui/ui_overlays.h
|
||||||
|
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -6,11 +6,17 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- Improved backdoor detection missbehaving magic s50/1k tag (Fl0-0)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- Added PAC/Stanley detection to lf search (marshmellow)
|
||||||
|
- Added lf pac demod and lf pac read - extracts the raw blocks from a PAC/Stanley tag (marshmellow)
|
||||||
|
- Added hf mf c* commands compatibity for 4k and gen1b backdoor (Fl0-0)
|
||||||
|
- Added backdoor detection for gen1b magic s70/4k tag (Fl0-0)
|
||||||
|
- Added data fsktonrz, a fsk cleaning/demodulating routine for weak fsk signal. Note: follow this up with a `data rawdemod nr` to finish demoding your signal. (marshmellow)
|
||||||
|
- Added lf em 410xbrute, LF EM410x reader bruteforce attack by simulating UIDs from a file (Fl0-0)
|
||||||
|
|
||||||
## [3.0.1][2017-06-08]
|
## [3.0.1][2017-06-08]
|
||||||
|
|
||||||
|
@ -22,6 +28,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
|
|
||||||
## [3.0.0][2017-06-05]
|
## [3.0.0][2017-06-05]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added lf hitag write 24, the command writes a block to hitag2 tags in crypto mode (henjo)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Added hf mf hardnested, an attack working for hardened Mifare cards (EV1, Mifare Plus SL1) where hf mf nested fails
|
- Added hf mf hardnested, an attack working for hardened Mifare cards (EV1, Mifare Plus SL1) where hf mf nested fails
|
||||||
- Added experimental testmode write option for t55xx (danger) (marshmellow)
|
- Added experimental testmode write option for t55xx (danger) (marshmellow)
|
||||||
|
|
|
@ -3,7 +3,7 @@ The project compiles on Linux, Mac OS X and Windows (MinGW/MSYS).
|
||||||
it requires:
|
it requires:
|
||||||
- gcc >= 4.4
|
- gcc >= 4.4
|
||||||
- libpthread
|
- libpthread
|
||||||
- libreadline
|
- GNU libreadline or BSD libedit (editline)
|
||||||
- libusb
|
- libusb
|
||||||
- perl
|
- perl
|
||||||
- an ARM cross-compiler to compile the firmware
|
- an ARM cross-compiler to compile the firmware
|
||||||
|
@ -109,7 +109,7 @@ Tested on OSX 10.10 Yosemite
|
||||||
1 - Install Xcode and Xcode Command Line Tools
|
1 - Install Xcode and Xcode Command Line Tools
|
||||||
|
|
||||||
2 - Install Homebrew and dependencies
|
2 - Install Homebrew and dependencies
|
||||||
brew install readline libusb p7zip libusb-compat wget qt5 pkgconfig
|
brew install libusb p7zip libusb-compat wget qt5 pkgconfig
|
||||||
|
|
||||||
3 - Install DevKitARM for OSX
|
3 - Install DevKitARM for OSX
|
||||||
Option 1:
|
Option 1:
|
||||||
|
@ -119,12 +119,10 @@ Tested on OSX 10.10 Yosemite
|
||||||
brew tap nitsky/stm32
|
brew tap nitsky/stm32
|
||||||
brew install arm-none-eabi-gcc
|
brew install arm-none-eabi-gcc
|
||||||
|
|
||||||
4 - Edit proxmark3/client/Makefile adding path to readline and qt5
|
4 - Edit proxmark3/client/Makefile adding path qt5
|
||||||
|
|
||||||
LDLIBS = -L/usr/local/opt/readline/lib -L/usr/local/opt/qt5/lib -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
|
LDLIBS = -L/usr/local/opt/qt5/lib -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
|
||||||
CFLAGS = -std=c99 -I/usr/local/opt/qt5/include -I/usr/local/opt/readline/include -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
CFLAGS = -std=c99 -I/usr/local/opt/qt5/include -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
||||||
|
|
||||||
If your old brew intallation use /usr/local/Cellar/ path replace /usr/local/opt/readline/lib with your actuall readline and qt5 path. See homebrew manuals.
|
|
||||||
|
|
||||||
5 - Set Environment
|
5 - Set Environment
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,14 @@
|
||||||
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
|
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
|
||||||
// Also used to hold various smaller buffers and the Mifare Emulator Memory.
|
// Also used to hold various smaller buffers and the Mifare Emulator Memory.
|
||||||
|
|
||||||
|
/* BigBuf memory layout:
|
||||||
|
Pointer to highest available memory: BigBuf_hi
|
||||||
|
|
||||||
|
high BIGBUF_SIZE
|
||||||
|
reserved = BigBuf_malloc() subtracts amount from BigBuf_hi,
|
||||||
|
low 0x00
|
||||||
|
*/
|
||||||
|
|
||||||
// declare it as uint32_t to achieve alignment to 4 Byte boundary
|
// declare it as uint32_t to achieve alignment to 4 Byte boundary
|
||||||
static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)];
|
static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)];
|
||||||
|
|
||||||
|
@ -41,7 +49,8 @@ uint8_t *BigBuf_get_addr(void)
|
||||||
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
||||||
uint8_t *BigBuf_get_EM_addr(void)
|
uint8_t *BigBuf_get_EM_addr(void)
|
||||||
{
|
{
|
||||||
if (emulator_memory == NULL) { // not yet allocated
|
// not yet allocated
|
||||||
|
if (emulator_memory == NULL) {
|
||||||
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
|
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +70,9 @@ void BigBuf_Clear_ext(bool verbose)
|
||||||
if (verbose)
|
if (verbose)
|
||||||
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
|
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
|
||||||
}
|
}
|
||||||
|
void BigBuf_Clear_EM(void){
|
||||||
|
memset(BigBuf_get_EM_addr(), 0, CARD_MEMORY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
void BigBuf_Clear_keep_EM(void)
|
void BigBuf_Clear_keep_EM(void)
|
||||||
{
|
{
|
||||||
|
@ -103,7 +115,7 @@ void BigBuf_print_status(void)
|
||||||
{
|
{
|
||||||
Dbprintf("Memory");
|
Dbprintf("Memory");
|
||||||
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
|
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
|
||||||
Dbprintf(" BigBuf_hi .............%d", BigBuf_hi);
|
Dbprintf(" Available memory........%d", BigBuf_hi);
|
||||||
Dbprintf("Tracing");
|
Dbprintf("Tracing");
|
||||||
Dbprintf(" tracing ................%d", tracing);
|
Dbprintf(" tracing ................%d", tracing);
|
||||||
Dbprintf(" traceLen ...............%d", traceLen);
|
Dbprintf(" traceLen ...............%d", traceLen);
|
||||||
|
@ -142,7 +154,7 @@ uint16_t BigBuf_get_traceLen(void)
|
||||||
**/
|
**/
|
||||||
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag)
|
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag)
|
||||||
{
|
{
|
||||||
if (!tracing) return FALSE;
|
if (!tracing) return false;
|
||||||
|
|
||||||
uint8_t *trace = BigBuf_get_addr();
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
|
|
||||||
|
@ -153,8 +165,8 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||||
uint16_t max_traceLen = BigBuf_max_traceLen();
|
uint16_t max_traceLen = BigBuf_max_traceLen();
|
||||||
|
|
||||||
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) {
|
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) {
|
||||||
tracing = FALSE; // don't trace any more
|
tracing = false; // don't trace any more
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
// Traceformat:
|
// Traceformat:
|
||||||
// 32 bits timestamp (little endian)
|
// 32 bits timestamp (little endian)
|
||||||
|
@ -198,7 +210,7 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||||
}
|
}
|
||||||
traceLen += num_paritybytes;
|
traceLen += num_paritybytes;
|
||||||
|
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,12 +221,12 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP
|
||||||
that this logger takes number of bits as argument, not number of bytes.
|
that this logger takes number of bits as argument, not number of bytes.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
if (!tracing) return FALSE;
|
if (!tracing) return false;
|
||||||
|
|
||||||
uint8_t *trace = BigBuf_get_addr();
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
uint16_t iLen = nbytes(iBits);
|
uint16_t iLen = nbytes(iBits);
|
||||||
// Return when trace is full
|
// Return when trace is full
|
||||||
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return FALSE;
|
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return false;
|
||||||
|
|
||||||
//Hitag traces appear to use this traceformat:
|
//Hitag traces appear to use this traceformat:
|
||||||
// 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
|
// 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
|
||||||
|
@ -241,19 +253,17 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP
|
||||||
memcpy(trace + traceLen, btBytes, iLen);
|
memcpy(trace + traceLen, btBytes, iLen);
|
||||||
traceLen += iLen;
|
traceLen += iLen;
|
||||||
|
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Emulator memory
|
// Emulator memory
|
||||||
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
|
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
|
||||||
uint8_t* mem = BigBuf_get_EM_addr();
|
uint8_t* mem = BigBuf_get_EM_addr();
|
||||||
if(offset+length < CARD_MEMORY_SIZE)
|
if (offset+length < CARD_MEMORY_SIZE) {
|
||||||
{
|
|
||||||
memcpy(mem+offset, data, length);
|
memcpy(mem+offset, data, length);
|
||||||
return 0;
|
return 0;
|
||||||
}else
|
} else {
|
||||||
{
|
|
||||||
Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset+length), CARD_MEMORY_SIZE);
|
Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset+length), CARD_MEMORY_SIZE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,13 @@ extern uint16_t BigBuf_max_traceLen(void);
|
||||||
extern void BigBuf_Clear(void);
|
extern void BigBuf_Clear(void);
|
||||||
extern void BigBuf_Clear_ext(bool verbose);
|
extern void BigBuf_Clear_ext(bool verbose);
|
||||||
extern void BigBuf_Clear_keep_EM(void);
|
extern void BigBuf_Clear_keep_EM(void);
|
||||||
|
extern void BigBuf_Clear_EM(void);
|
||||||
extern uint8_t *BigBuf_malloc(uint16_t);
|
extern uint8_t *BigBuf_malloc(uint16_t);
|
||||||
extern void BigBuf_free(void);
|
extern void BigBuf_free(void);
|
||||||
extern void BigBuf_free_keep_EM(void);
|
extern void BigBuf_free_keep_EM(void);
|
||||||
extern void BigBuf_print_status(void);
|
extern void BigBuf_print_status(void);
|
||||||
extern uint16_t BigBuf_get_traceLen(void);
|
extern uint16_t BigBuf_get_traceLen(void);
|
||||||
extern void clear_trace();
|
extern void clear_trace(void);
|
||||||
extern void set_tracing(bool enable);
|
extern void set_tracing(bool enable);
|
||||||
extern bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
|
extern bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
|
||||||
extern int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader);
|
extern int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader);
|
||||||
|
|
|
@ -1152,7 +1152,7 @@ int main()
|
||||||
if( AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0)
|
if( AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0)
|
||||||
printf("init error\n");
|
printf("init error\n");
|
||||||
|
|
||||||
if (AesEncrypt(&ctx, databuf, databuf, sizeof databuf) < 0)
|
if (AesEncrypt(&ctx, databuf, databuf, sizeof(databuf) ) < 0)
|
||||||
printf("error in encryption\n");
|
printf("error in encryption\n");
|
||||||
|
|
||||||
// initialize context and decrypt cipher at other end
|
// initialize context and decrypt cipher at other end
|
||||||
|
@ -1160,7 +1160,7 @@ int main()
|
||||||
if( AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0)
|
if( AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0)
|
||||||
printf("init error\n");
|
printf("init error\n");
|
||||||
|
|
||||||
if (AesDecrypt(&ctx, databuf, databuf, sizeof databuf) < 0)
|
if (AesDecrypt(&ctx, databuf, databuf, sizeof(databuf) ) < 0)
|
||||||
printf("error in decryption\n");
|
printf("error in decryption\n");
|
||||||
|
|
||||||
printf("%s\n", databuf);
|
printf("%s\n", databuf);
|
||||||
|
|
|
@ -1051,7 +1051,12 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
ReadHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
|
ReadHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
case CMD_WR_HITAG_S://writer for Hitag tags args=data to write,page and key or challenge
|
case CMD_WR_HITAG_S://writer for Hitag tags args=data to write,page and key or challenge
|
||||||
|
if ((hitag_function)c->arg[0] < 10) {
|
||||||
WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
|
WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
|
||||||
|
}
|
||||||
|
else if ((hitag_function)c->arg[0] >= 10) {
|
||||||
|
WriterHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes, c->arg[2]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,7 @@ void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType);
|
||||||
void SnoopHitag(uint32_t type);
|
void SnoopHitag(uint32_t type);
|
||||||
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data);
|
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data);
|
||||||
void ReaderHitag(hitag_function htf, hitag_data* htd);
|
void ReaderHitag(hitag_function htf, hitag_data* htd);
|
||||||
|
void WriterHitag(hitag_function htf, hitag_data* htd, int page);
|
||||||
|
|
||||||
//hitagS.h
|
//hitagS.h
|
||||||
void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data);
|
void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data);
|
||||||
|
|
|
@ -158,9 +158,7 @@ void FpgaSetupSsc(void)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
bool FpgaSetupSscDma(uint8_t *buf, int len)
|
bool FpgaSetupSscDma(uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
if (buf == NULL) {
|
if (buf == NULL) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer
|
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer
|
||||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address
|
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address
|
||||||
|
@ -184,13 +182,12 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8
|
||||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
||||||
fpga_image_ptr = output_buffer;
|
fpga_image_ptr = output_buffer;
|
||||||
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
|
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
|
||||||
if (res != Z_OK) {
|
if (res != Z_OK)
|
||||||
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
|
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
|
||||||
}
|
|
||||||
if (res < 0) {
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
uncompressed_bytes_cnt++;
|
uncompressed_bytes_cnt++;
|
||||||
|
|
||||||
|
@ -222,7 +219,7 @@ static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size)
|
||||||
|
|
||||||
static void fpga_inflate_free(voidpf opaque, voidpf address)
|
static void fpga_inflate_free(voidpf opaque, voidpf address)
|
||||||
{
|
{
|
||||||
BigBuf_free();
|
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,7 +274,7 @@ static void DownloadFPGA_byte(unsigned char w)
|
||||||
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
|
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
|
||||||
{
|
{
|
||||||
|
|
||||||
Dbprintf("DownloadFPGA(len: %d)", FpgaImageLen);
|
//Dbprintf("DownloadFPGA(len: %d)", FpgaImageLen);
|
||||||
|
|
||||||
int i=0;
|
int i=0;
|
||||||
|
|
||||||
|
@ -416,14 +413,14 @@ static int bitparse_find_section(int bitstream_version, char section_name, unsig
|
||||||
void FpgaDownloadAndGo(int bitstream_version)
|
void FpgaDownloadAndGo(int bitstream_version)
|
||||||
{
|
{
|
||||||
z_stream compressed_fpga_stream;
|
z_stream compressed_fpga_stream;
|
||||||
uint8_t output_buffer[OUTPUT_BUFFER_LEN];
|
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
|
||||||
|
|
||||||
// check whether or not the bitstream is already loaded
|
// check whether or not the bitstream is already loaded
|
||||||
if (downloaded_bitstream == bitstream_version)
|
if (downloaded_bitstream == bitstream_version)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// make sure that we have enough memory to decompress
|
// make sure that we have enough memory to decompress
|
||||||
BigBuf_free();
|
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) {
|
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) {
|
||||||
return;
|
return;
|
||||||
|
@ -436,6 +433,9 @@ void FpgaDownloadAndGo(int bitstream_version)
|
||||||
}
|
}
|
||||||
|
|
||||||
inflateEnd(&compressed_fpga_stream);
|
inflateEnd(&compressed_fpga_stream);
|
||||||
|
|
||||||
|
// free eventually allocated BigBuf memory
|
||||||
|
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -448,18 +448,17 @@ void FpgaDownloadAndGo(int bitstream_version)
|
||||||
void FpgaGatherVersion(int bitstream_version, char *dst, int len)
|
void FpgaGatherVersion(int bitstream_version, char *dst, int len)
|
||||||
{
|
{
|
||||||
unsigned int fpga_info_len;
|
unsigned int fpga_info_len;
|
||||||
char tempstr[40];
|
char tempstr[40] = {0x00};
|
||||||
z_stream compressed_fpga_stream;
|
z_stream compressed_fpga_stream;
|
||||||
uint8_t output_buffer[OUTPUT_BUFFER_LEN];
|
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
|
||||||
|
|
||||||
dst[0] = '\0';
|
dst[0] = '\0';
|
||||||
|
|
||||||
// ensure that we can allocate enough memory for decompression:
|
// ensure that we can allocate enough memory for decompression:
|
||||||
BigBuf_free();
|
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) {
|
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if(bitparse_find_section(bitstream_version, 'a', &fpga_info_len, &compressed_fpga_stream, output_buffer)) {
|
if(bitparse_find_section(bitstream_version, 'a', &fpga_info_len, &compressed_fpga_stream, output_buffer)) {
|
||||||
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
||||||
|
@ -559,12 +558,13 @@ void SetAdcMuxFor(uint32_t whichGpio)
|
||||||
HIGH(whichGpio);
|
HIGH(whichGpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fpga_print_status(void)
|
void Fpga_print_status(void) {
|
||||||
{
|
|
||||||
Dbprintf("Fgpa");
|
Dbprintf("Fgpa");
|
||||||
if(downloaded_bitstream == FPGA_BITSTREAM_HF) Dbprintf(" mode.............HF");
|
switch(downloaded_bitstream) {
|
||||||
else if(downloaded_bitstream == FPGA_BITSTREAM_LF) Dbprintf(" mode.............LF");
|
case FPGA_BITSTREAM_HF: Dbprintf(" mode....................HF"); break;
|
||||||
else Dbprintf(" mode.............%d", downloaded_bitstream);
|
case FPGA_BITSTREAM_LF: Dbprintf(" mode....................LF"); break;
|
||||||
|
default: Dbprintf(" mode....................%d", downloaded_bitstream); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FpgaGetCurrent() {
|
int FpgaGetCurrent() {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "BigBuf.h"
|
#include "BigBuf.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||||
|
|
||||||
static void RAMFUNC optimizedSnoop(void);
|
static void RAMFUNC optimizedSnoop(void);
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ static void RAMFUNC optimizedSnoop(void)
|
||||||
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)
|
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)
|
||||||
{
|
{
|
||||||
*dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
*dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
||||||
dest = dest + 1;
|
dest++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Resetting Frame mode (First set in fpgaloader.c)
|
//Resetting Frame mode (First set in fpgaloader.c)
|
||||||
|
@ -28,7 +29,9 @@ static void RAMFUNC optimizedSnoop(void)
|
||||||
|
|
||||||
void HfSnoop(int samplesToSkip, int triggersToSkip)
|
void HfSnoop(int samplesToSkip, int triggersToSkip)
|
||||||
{
|
{
|
||||||
Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.", samplesToSkip, triggersToSkip);
|
BigBuf_free(); BigBuf_Clear();
|
||||||
|
|
||||||
|
Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
|
||||||
int trigger_cnt;
|
int trigger_cnt;
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
// Select correct configs
|
// Select correct configs
|
||||||
|
@ -40,34 +43,28 @@ void HfSnoop(int samplesToSkip, int triggersToSkip)
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
|
|
||||||
BigBuf_free();
|
|
||||||
BigBuf_Clear();
|
|
||||||
|
|
||||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16); // Setting Frame Mode For better performance on high speed data transfer.
|
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16); // Setting Frame Mode For better performance on high speed data transfer.
|
||||||
|
|
||||||
trigger_cnt = 0;
|
trigger_cnt = 0;
|
||||||
uint16_t r = 0;
|
uint16_t r = 0;
|
||||||
while(!BUTTON_PRESS()) {
|
while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
r = (uint16_t)AT91C_BASE_SSC->SSC_RHR;
|
r = (uint16_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
r = MAX(r & 0xff, r >> 8);
|
r = MAX(r & 0xff, r >> 8);
|
||||||
if (r >= 240)
|
if (r >= 240) {
|
||||||
{
|
if (++trigger_cnt > triggersToSkip)
|
||||||
if (++trigger_cnt > triggersToSkip) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(!BUTTON_PRESS()) {
|
if(!BUTTON_PRESS()) {
|
||||||
int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0
|
int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0
|
||||||
while(waitcount != 0) {
|
while(waitcount != 0) {
|
||||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY))
|
||||||
waitcount--;
|
waitcount--;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
optimizedSnoop();
|
optimizedSnoop();
|
||||||
Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r);
|
Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r);
|
||||||
}
|
}
|
||||||
|
|
372
armsrc/hitag2.c
372
armsrc/hitag2.c
|
@ -64,6 +64,13 @@ static struct hitag2_tag tag = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static enum {
|
||||||
|
WRITE_STATE_START = 0x0,
|
||||||
|
WRITE_STATE_PAGENUM_WRITTEN,
|
||||||
|
WRITE_STATE_PROG
|
||||||
|
} writestate;
|
||||||
|
|
||||||
|
|
||||||
// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces.
|
// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces.
|
||||||
// Historically it used to be FREE_BUFFER_SIZE, which was 2744.
|
// Historically it used to be FREE_BUFFER_SIZE, which was 2744.
|
||||||
#define AUTH_TABLE_LENGTH 2744
|
#define AUTH_TABLE_LENGTH 2744
|
||||||
|
@ -74,6 +81,7 @@ static size_t auth_table_len = AUTH_TABLE_LENGTH;
|
||||||
static byte_t password[4];
|
static byte_t password[4];
|
||||||
static byte_t NrAr[8];
|
static byte_t NrAr[8];
|
||||||
static byte_t key[8];
|
static byte_t key[8];
|
||||||
|
static byte_t writedata[4];
|
||||||
static uint64_t cipher_state;
|
static uint64_t cipher_state;
|
||||||
|
|
||||||
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
|
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
|
||||||
|
@ -222,6 +230,7 @@ static int hitag2_cipher_transcrypt(uint64_t* cs, byte_t *data, unsigned int byt
|
||||||
#define HITAG_T_WAIT_1 200 /* T_wresp should be 199..206 */
|
#define HITAG_T_WAIT_1 200 /* T_wresp should be 199..206 */
|
||||||
#define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */
|
#define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */
|
||||||
#define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */
|
#define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */
|
||||||
|
#define HITAG_T_PROG 614
|
||||||
|
|
||||||
#define HITAG_T_TAG_ONE_HALF_PERIOD 10
|
#define HITAG_T_TAG_ONE_HALF_PERIOD 10
|
||||||
#define HITAG_T_TAG_TWO_HALF_PERIOD 25
|
#define HITAG_T_TAG_TWO_HALF_PERIOD 25
|
||||||
|
@ -507,18 +516,70 @@ static bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t*
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
static bool hitag2_write_page(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
||||||
|
{
|
||||||
|
switch (writestate) {
|
||||||
|
case WRITE_STATE_START:
|
||||||
|
*txlen = 10;
|
||||||
|
tx[0] = 0x82 | (blocknr << 3) | ((blocknr^7) >> 2);
|
||||||
|
tx[1] = ((blocknr^7) << 6);
|
||||||
|
writestate = WRITE_STATE_PAGENUM_WRITTEN;
|
||||||
|
break;
|
||||||
|
case WRITE_STATE_PAGENUM_WRITTEN:
|
||||||
|
// Check if page number was received correctly
|
||||||
|
if ((rxlen == 10) &&
|
||||||
|
(rx[0] == (0x82 | (blocknr << 3) | ((blocknr^7) >> 2))) &&
|
||||||
|
(rx[1] == (((blocknr & 0x3) ^ 0x3) << 6))) {
|
||||||
|
*txlen = 32;
|
||||||
|
memset(tx, 0, HITAG_FRAME_LEN);
|
||||||
|
memcpy(tx, writedata, 4);
|
||||||
|
writestate = WRITE_STATE_PROG;
|
||||||
|
} else {
|
||||||
|
Dbprintf("hitag2_write_page: Page number was not received correctly: rxlen=%d rx=%02x%02x%02x%02x",
|
||||||
|
rxlen, rx[0], rx[1], rx[2], rx[3]);
|
||||||
|
bSuccessful = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WRITE_STATE_PROG:
|
||||||
|
if (rxlen == 0) {
|
||||||
|
bSuccessful = true;
|
||||||
|
} else {
|
||||||
|
bSuccessful = false;
|
||||||
|
Dbprintf("hitag2_write_page: unexpected rx data (%d) after page write", rxlen);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
DbpString("hitag2_write_page: Unknown state %d");
|
||||||
|
bSuccessful = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen, bool write) {
|
||||||
// Reset the transmission frame length
|
// Reset the transmission frame length
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
|
|
||||||
if(bCrypto) {
|
if(bCrypto) {
|
||||||
hitag2_cipher_transcrypt(&cipher_state,rx,rxlen/8,rxlen%8);
|
hitag2_cipher_transcrypt(&cipher_state,rx,rxlen/8,rxlen%8);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bCrypto && !bAuthenticating && write) {
|
||||||
|
if (!hitag2_write_page(rx, rxlen, tx, txlen)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
// Try to find out which command was send by selecting on length (in bits)
|
// Try to find out which command was send by selecting on length (in bits)
|
||||||
switch (rxlen) {
|
switch (rxlen) {
|
||||||
// No answer, try to resurrect
|
// No answer, try to resurrect
|
||||||
case 0: {
|
case 0:
|
||||||
|
{
|
||||||
// Stop if there is no answer while we are in crypto mode (after sending NrAr)
|
// Stop if there is no answer while we are in crypto mode (after sending NrAr)
|
||||||
if (bCrypto) {
|
if (bCrypto) {
|
||||||
// Failed during authentication
|
// Failed during authentication
|
||||||
|
@ -547,17 +608,18 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
|
||||||
*txlen = 5;
|
*txlen = 5;
|
||||||
memcpy(tx,"\xc0",nbytes(*txlen));
|
memcpy(tx,"\xc0",nbytes(*txlen));
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
// Received UID, crypto tag answer
|
// Received UID, crypto tag answer
|
||||||
case 32: {
|
case 32: {
|
||||||
if (!bCrypto) {
|
if (!bCrypto) {
|
||||||
uint64_t ui64key = key[0] | ((uint64_t)key[1]) << 8 | ((uint64_t)key[2]) << 16 | ((uint64_t)key[3]) << 24 | ((uint64_t)key[4]) << 32 | ((uint64_t)key[5]) << 40;
|
uint64_t ui64key = key[0] | ((uint64_t)key[1]) << 8 | ((uint64_t)key[2]) << 16 | ((uint64_t)key[3]) << 24 | ((uint64_t)key[4]) << 32 | ((uint64_t)key[5]) << 40;
|
||||||
uint32_t ui32uid = rx[0] | ((uint32_t)rx[1]) << 8 | ((uint32_t)rx[2]) << 16 | ((uint32_t)rx[3]) << 24;
|
uint32_t ui32uid = rx[0] | ((uint32_t)rx[1]) << 8 | ((uint32_t)rx[2]) << 16 | ((uint32_t)rx[3]) << 24;
|
||||||
|
Dbprintf("hitag2_crypto: key=0x%x%x uid=0x%x", (uint32_t) ((rev64(ui64key)) >> 32), (uint32_t) ((rev64(ui64key)) & 0xffffffff), rev32(ui32uid));
|
||||||
cipher_state = _hitag2_init(rev64(ui64key), rev32(ui32uid), 0);
|
cipher_state = _hitag2_init(rev64(ui64key), rev32(ui32uid), 0);
|
||||||
memset(tx,0x00,4);
|
memset(tx,0x00,4);
|
||||||
memset(tx+4,0xff,4);
|
memset(tx+4,0xff,4);
|
||||||
hitag2_cipher_transcrypt(&cipher_state,tx+4,4,0);
|
hitag2_cipher_transcrypt(&cipher_state, tx+4, 4, 0);
|
||||||
*txlen = 64;
|
*txlen = 64;
|
||||||
bCrypto = true;
|
bCrypto = true;
|
||||||
bAuthenticating = true;
|
bAuthenticating = true;
|
||||||
|
@ -565,20 +627,28 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
|
||||||
// Check if we received answer tag (at)
|
// Check if we received answer tag (at)
|
||||||
if (bAuthenticating) {
|
if (bAuthenticating) {
|
||||||
bAuthenticating = false;
|
bAuthenticating = false;
|
||||||
|
if (write) {
|
||||||
|
if (!hitag2_write_page(rx, rxlen, tx, txlen)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Store the received block
|
// Store the received block
|
||||||
memcpy(tag.sectors[blocknr],rx,4);
|
memcpy(tag.sectors[blocknr],rx,4);
|
||||||
blocknr++;
|
blocknr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocknr > 7) {
|
if (blocknr > 7) {
|
||||||
DbpString("Read succesful!");
|
DbpString("Read succesful!");
|
||||||
bSuccessful = true;
|
bSuccessful = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
*txlen = 10;
|
*txlen = 10;
|
||||||
tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2);
|
tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2);
|
||||||
tx[1] = ((blocknr^7) << 6);
|
tx[1] = ((blocknr^7) << 6);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// Unexpected response
|
// Unexpected response
|
||||||
|
@ -587,7 +657,7 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
|
||||||
return false;
|
return false;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(bCrypto) {
|
if(bCrypto) {
|
||||||
// We have to return now to avoid double encryption
|
// We have to return now to avoid double encryption
|
||||||
|
@ -792,7 +862,6 @@ void SnoopHitag(uint32_t type) {
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
|
|
||||||
// Reset the received frame, frame count and timing info
|
// Reset the received frame, frame count and timing info
|
||||||
memset(rx,0x00,sizeof(rx));
|
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
response = 0;
|
response = 0;
|
||||||
overflow = 0;
|
overflow = 0;
|
||||||
|
@ -1180,7 +1249,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||||
bAuthenticating = false;
|
bAuthenticating = false;
|
||||||
bQuitTraceFull = true;
|
bQuitTraceFull = true;
|
||||||
} break;
|
} break;
|
||||||
case RHT2F_CRYPTO: {
|
case RHT2F_CRYPTO:
|
||||||
|
{
|
||||||
DbpString("Authenticating using key:");
|
DbpString("Authenticating using key:");
|
||||||
memcpy(key,htd->crypto.key,6); //HACK; 4 or 6?? I read both in the code.
|
memcpy(key,htd->crypto.key,6); //HACK; 4 or 6?? I read both in the code.
|
||||||
Dbhexdump(6,key,false);
|
Dbhexdump(6,key,false);
|
||||||
|
@ -1306,7 +1376,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||||
bStop = !hitag2_authenticate(rx,rxlen,tx,&txlen);
|
bStop = !hitag2_authenticate(rx,rxlen,tx,&txlen);
|
||||||
} break;
|
} break;
|
||||||
case RHT2F_CRYPTO: {
|
case RHT2F_CRYPTO: {
|
||||||
bStop = !hitag2_crypto(rx,rxlen,tx,&txlen);
|
bStop = !hitag2_crypto(rx,rxlen,tx,&txlen, false);
|
||||||
} break;
|
} break;
|
||||||
case RHT2F_TEST_AUTH_ATTEMPTS: {
|
case RHT2F_TEST_AUTH_ATTEMPTS: {
|
||||||
bStop = !hitag2_test_auth_attempts(rx,rxlen,tx,&txlen);
|
bStop = !hitag2_test_auth_attempts(rx,rxlen,tx,&txlen);
|
||||||
|
@ -1453,3 +1523,285 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||||
//DbpString("All done");
|
//DbpString("All done");
|
||||||
cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48);
|
cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriterHitag(hitag_function htf, hitag_data* htd, int page) {
|
||||||
|
int frame_count;
|
||||||
|
int response;
|
||||||
|
byte_t rx[HITAG_FRAME_LEN];
|
||||||
|
size_t rxlen=0;
|
||||||
|
byte_t txbuf[HITAG_FRAME_LEN];
|
||||||
|
byte_t* tx = txbuf;
|
||||||
|
size_t txlen=0;
|
||||||
|
int lastbit;
|
||||||
|
bool bSkip;
|
||||||
|
int reset_sof;
|
||||||
|
int tag_sof;
|
||||||
|
int t_wait = HITAG_T_WAIT_MAX;
|
||||||
|
bool bStop;
|
||||||
|
bool bQuitTraceFull = false;
|
||||||
|
|
||||||
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
|
// Reset the return status
|
||||||
|
bSuccessful = false;
|
||||||
|
|
||||||
|
// Clean up trace and prepare it for storing frames
|
||||||
|
set_tracing(TRUE);
|
||||||
|
clear_trace();
|
||||||
|
|
||||||
|
//DbpString("Starting Hitag reader family");
|
||||||
|
|
||||||
|
// Check configuration
|
||||||
|
switch(htf) {
|
||||||
|
case WHT2F_CRYPTO:
|
||||||
|
{
|
||||||
|
DbpString("Authenticating using key:");
|
||||||
|
memcpy(key,htd->crypto.key,6); //HACK; 4 or 6?? I read both in the code.
|
||||||
|
memcpy(writedata, htd->crypto.data, 4);
|
||||||
|
Dbhexdump(6,key,false);
|
||||||
|
blocknr = page;
|
||||||
|
bQuiet = false;
|
||||||
|
bCrypto = false;
|
||||||
|
bAuthenticating = false;
|
||||||
|
bQuitTraceFull = true;
|
||||||
|
writestate = WRITE_STATE_START;
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
Dbprintf("Error, unknown function: %d",htf);
|
||||||
|
return;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_D_ON();
|
||||||
|
hitag2_init();
|
||||||
|
|
||||||
|
// Configure output and enable pin that is connected to the FPGA (for modulating)
|
||||||
|
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||||
|
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||||
|
|
||||||
|
// Set fpga in edge detect with reader field, we can modulate as reader now
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||||
|
|
||||||
|
// Set Frequency divisor which will drive the FPGA and analog mux selection
|
||||||
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||||
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
RELAY_OFF();
|
||||||
|
|
||||||
|
// Disable modulation at default, which means enable the field
|
||||||
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
|
||||||
|
// Give it a bit of time for the resonant antenna to settle.
|
||||||
|
SpinDelay(30);
|
||||||
|
|
||||||
|
// Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering
|
||||||
|
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);
|
||||||
|
|
||||||
|
// Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames
|
||||||
|
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
|
||||||
|
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||||
|
|
||||||
|
// Disable timer during configuration
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
|
||||||
|
// Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||||
|
// external trigger rising edge, load RA on falling edge of TIOA.
|
||||||
|
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING;
|
||||||
|
|
||||||
|
// Enable and reset counters
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
|
|
||||||
|
// Reset the received frame, frame count and timing info
|
||||||
|
frame_count = 0;
|
||||||
|
response = 0;
|
||||||
|
lastbit = 1;
|
||||||
|
bStop = false;
|
||||||
|
|
||||||
|
// Tag specific configuration settings (sof, timings, etc.)
|
||||||
|
if (htf < 10){
|
||||||
|
// hitagS settings
|
||||||
|
reset_sof = 1;
|
||||||
|
t_wait = 200;
|
||||||
|
//DbpString("Configured for hitagS reader");
|
||||||
|
} else if (htf < 20) {
|
||||||
|
// hitag1 settings
|
||||||
|
reset_sof = 1;
|
||||||
|
t_wait = 200;
|
||||||
|
//DbpString("Configured for hitag1 reader");
|
||||||
|
} else if (htf < 30) {
|
||||||
|
// hitag2 settings
|
||||||
|
reset_sof = 4;
|
||||||
|
t_wait = HITAG_T_WAIT_2;
|
||||||
|
//DbpString("Configured for hitag2 reader");
|
||||||
|
} else {
|
||||||
|
Dbprintf("Error, unknown hitag reader type: %d",htf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(!bStop && !BUTTON_PRESS()) {
|
||||||
|
// Watchdog hit
|
||||||
|
WDT_HIT();
|
||||||
|
|
||||||
|
// Check if frame was captured and store it
|
||||||
|
if(rxlen > 0) {
|
||||||
|
frame_count++;
|
||||||
|
if (!bQuiet) {
|
||||||
|
if (!LogTraceHitag(rx,rxlen,response,0,false)) {
|
||||||
|
DbpString("Trace full");
|
||||||
|
if (bQuitTraceFull) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
bQuiet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// By default reset the transmission buffer
|
||||||
|
tx = txbuf;
|
||||||
|
switch(htf) {
|
||||||
|
case WHT2F_CRYPTO: {
|
||||||
|
bStop = !hitag2_crypto(rx,rxlen,tx,&txlen, true);
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
Dbprintf("Error, unknown function: %d",htf);
|
||||||
|
return;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send and store the reader command
|
||||||
|
// Disable timer 1 with external trigger to avoid triggers during our own modulation
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
|
||||||
|
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
||||||
|
// Since the clock counts since the last falling edge, a 'one' means that the
|
||||||
|
// falling edge occured halfway the period. with respect to this falling edge,
|
||||||
|
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
||||||
|
// All timer values are in terms of T0 units
|
||||||
|
while(AT91C_BASE_TC0->TC_CV < T0*(t_wait+(HITAG_T_TAG_HALF_PERIOD*lastbit)));
|
||||||
|
|
||||||
|
//Dbprintf("DEBUG: Sending reader frame");
|
||||||
|
|
||||||
|
// Transmit the reader frame
|
||||||
|
hitag_reader_send_frame(tx,txlen);
|
||||||
|
|
||||||
|
// Enable and reset external trigger in timer for capturing future frames
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
|
|
||||||
|
// Add transmitted frame to total count
|
||||||
|
if(txlen > 0) {
|
||||||
|
frame_count++;
|
||||||
|
if (!bQuiet) {
|
||||||
|
// Store the frame in the trace
|
||||||
|
if (!LogTraceHitag(tx,txlen,HITAG_T_WAIT_2,0,true)) {
|
||||||
|
if (bQuitTraceFull) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
bQuiet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset values for receiving frames
|
||||||
|
memset(rx,0x00,sizeof(rx));
|
||||||
|
rxlen = 0;
|
||||||
|
lastbit = 1;
|
||||||
|
bSkip = true;
|
||||||
|
tag_sof = reset_sof;
|
||||||
|
response = 0;
|
||||||
|
//Dbprintf("DEBUG: Waiting to receive frame");
|
||||||
|
uint32_t errorCount = 0;
|
||||||
|
|
||||||
|
// Receive frame, watch for at most T0*EOF periods
|
||||||
|
while (AT91C_BASE_TC1->TC_CV < T0*HITAG_T_WAIT_MAX) {
|
||||||
|
// Check if falling edge in tag modulation is detected
|
||||||
|
if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
|
||||||
|
// Retrieve the new timing values
|
||||||
|
int ra = (AT91C_BASE_TC1->TC_RA/T0);
|
||||||
|
|
||||||
|
// Reset timer every frame, we have to capture the last edge for timing
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
|
||||||
|
LED_B_ON();
|
||||||
|
|
||||||
|
// Capture tag frame (manchester decoding using only falling edges)
|
||||||
|
if(ra >= HITAG_T_EOF) {
|
||||||
|
if (rxlen != 0) {
|
||||||
|
//Dbprintf("DEBUG: Wierd1");
|
||||||
|
}
|
||||||
|
// Capture the T0 periods that have passed since last communication or field drop (reset)
|
||||||
|
// We always recieve a 'one' first, which has the falling edge after a half period |-_|
|
||||||
|
response = ra-HITAG_T_TAG_HALF_PERIOD;
|
||||||
|
} else if(ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) {
|
||||||
|
// Manchester coding example |-_|_-|-_| (101)
|
||||||
|
|
||||||
|
//need to test to verify we don't exceed memory...
|
||||||
|
//if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) {
|
||||||
|
// break;
|
||||||
|
//}
|
||||||
|
rx[rxlen / 8] |= 0 << (7-(rxlen%8));
|
||||||
|
rxlen++;
|
||||||
|
rx[rxlen / 8] |= 1 << (7-(rxlen%8));
|
||||||
|
rxlen++;
|
||||||
|
} else if(ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) {
|
||||||
|
// Manchester coding example |_-|...|_-|-_| (0...01)
|
||||||
|
|
||||||
|
//need to test to verify we don't exceed memory...
|
||||||
|
//if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) {
|
||||||
|
// break;
|
||||||
|
//}
|
||||||
|
rx[rxlen / 8] |= 0 << (7-(rxlen%8));
|
||||||
|
rxlen++;
|
||||||
|
// We have to skip this half period at start and add the 'one' the second time
|
||||||
|
if (!bSkip) {
|
||||||
|
rx[rxlen / 8] |= 1 << (7-(rxlen%8));
|
||||||
|
rxlen++;
|
||||||
|
}
|
||||||
|
lastbit = !lastbit;
|
||||||
|
bSkip = !bSkip;
|
||||||
|
} else if(ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) {
|
||||||
|
// Manchester coding example |_-|_-| (00) or |-_|-_| (11)
|
||||||
|
|
||||||
|
//need to test to verify we don't exceed memory...
|
||||||
|
//if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) {
|
||||||
|
// break;
|
||||||
|
//}
|
||||||
|
if (tag_sof) {
|
||||||
|
// Ignore bits that are transmitted during SOF
|
||||||
|
tag_sof--;
|
||||||
|
} else {
|
||||||
|
// bit is same as last bit
|
||||||
|
rx[rxlen / 8] |= lastbit << (7-(rxlen%8));
|
||||||
|
rxlen++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Dbprintf("DEBUG: Wierd2");
|
||||||
|
errorCount++;
|
||||||
|
// Ignore wierd value, is to small to mean anything
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if we saw over 100 wierd values break it probably isn't hitag...
|
||||||
|
if (errorCount >100) break;
|
||||||
|
// We can break this loop if we received the last bit from a frame
|
||||||
|
if (AT91C_BASE_TC1->TC_CV > T0*HITAG_T_EOF) {
|
||||||
|
if (rxlen>0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait some extra time for flash to be programmed
|
||||||
|
if ((rxlen == 0) && (writestate == WRITE_STATE_PROG))
|
||||||
|
{
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
while(AT91C_BASE_TC0->TC_CV < T0*(HITAG_T_PROG - HITAG_T_WAIT_MAX));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Dbprintf("DEBUG: Done waiting for frame");
|
||||||
|
|
||||||
|
LED_B_OFF();
|
||||||
|
LED_D_OFF();
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
//Dbprintf("frame received: %d",frame_count);
|
||||||
|
//DbpString("All done");
|
||||||
|
cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48);
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "iso15693tools.h"
|
#include "iso15693tools.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "optimized_cipher.h"
|
#include "optimized_cipher.h"
|
||||||
|
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||||
|
|
||||||
static int timeout = 4096;
|
static int timeout = 4096;
|
||||||
|
|
||||||
|
@ -1661,7 +1662,7 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key)
|
||||||
//Flag that we got to at least stage 1, read CSN
|
//Flag that we got to at least stage 1, read CSN
|
||||||
read_status = 1;
|
read_status = 1;
|
||||||
|
|
||||||
// Card selected, now read e-purse (cc)
|
// Card selected, now read e-purse (cc) (only 8 bytes no CRC)
|
||||||
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
|
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
|
||||||
if(ReaderReceiveIClass(resp) == 8) {
|
if(ReaderReceiveIClass(resp) == 8) {
|
||||||
//Save CC (e-purse) in response data
|
//Save CC (e-purse) in response data
|
||||||
|
@ -1681,28 +1682,37 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
|
|
||||||
uint8_t card_data[6 * 8]={0};
|
uint8_t card_data[6 * 8]={0};
|
||||||
memset(card_data, 0xFF, sizeof(card_data));
|
memset(card_data, 0xFF, sizeof(card_data));
|
||||||
uint8_t last_csn[8]={0};
|
uint8_t last_csn[8]={0,0,0,0,0,0,0,0};
|
||||||
|
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||||
|
memset(resp, 0xFF, sizeof(resp));
|
||||||
//Read conf block CRC(0x01) => 0xfa 0x22
|
//Read conf block CRC(0x01) => 0xfa 0x22
|
||||||
uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x01, 0xfa, 0x22};
|
uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x01, 0xfa, 0x22};
|
||||||
//Read conf block CRC(0x05) => 0xde 0x64
|
//Read App Issuer Area block CRC(0x05) => 0xde 0x64
|
||||||
uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x05, 0xde, 0x64};
|
uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x05, 0xde, 0x64};
|
||||||
|
|
||||||
|
|
||||||
int read_status= 0;
|
int read_status= 0;
|
||||||
uint8_t result_status = 0;
|
uint8_t result_status = 0;
|
||||||
|
// flag to read until one tag is found successfully
|
||||||
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
|
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
|
||||||
|
// flag to only try 5 times to find one tag then return
|
||||||
bool try_once = arg0 & FLAG_ICLASS_READER_ONE_TRY;
|
bool try_once = arg0 & FLAG_ICLASS_READER_ONE_TRY;
|
||||||
bool use_credit_key = false;
|
// if neither abort_after_read nor try_once then continue reading until button pressed.
|
||||||
if (arg0 & FLAG_ICLASS_READER_CEDITKEY)
|
|
||||||
use_credit_key = true;
|
bool use_credit_key = arg0 & FLAG_ICLASS_READER_CEDITKEY;
|
||||||
set_tracing(TRUE);
|
// test flags for what blocks to be sure to read
|
||||||
|
uint8_t flagReadConfig = arg0 & FLAG_ICLASS_READER_CONF;
|
||||||
|
uint8_t flagReadCC = arg0 & FLAG_ICLASS_READER_CC;
|
||||||
|
uint8_t flagReadAA = arg0 & FLAG_ICLASS_READER_AA;
|
||||||
|
|
||||||
|
set_tracing(true);
|
||||||
setupIclassReader();
|
setupIclassReader();
|
||||||
|
|
||||||
uint16_t tryCnt=0;
|
uint16_t tryCnt=0;
|
||||||
while(!BUTTON_PRESS())
|
bool userCancelled = BUTTON_PRESS() || usb_poll_validate_length();
|
||||||
|
while(!userCancelled)
|
||||||
{
|
{
|
||||||
if (try_once && tryCnt > 5) break;
|
// if only looking for one card try 2 times if we missed it the first time
|
||||||
|
if (try_once && tryCnt > 2) break;
|
||||||
tryCnt++;
|
tryCnt++;
|
||||||
if(!tracing) {
|
if(!tracing) {
|
||||||
DbpString("Trace full");
|
DbpString("Trace full");
|
||||||
|
@ -1721,21 +1731,22 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
// moving CC forward 8 bytes
|
// moving CC forward 8 bytes
|
||||||
memcpy(card_data+16,card_data+8, 8);
|
memcpy(card_data+16,card_data+8, 8);
|
||||||
//Read block 1, config
|
//Read block 1, config
|
||||||
if(arg0 & FLAG_ICLASS_READER_CONF)
|
if(flagReadConfig) {
|
||||||
{
|
if(sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, 10, 10))
|
||||||
if(sendCmdGetResponseWithRetries(readConf, sizeof(readConf),card_data+8, 10, 10))
|
|
||||||
{
|
{
|
||||||
result_status |= FLAG_ICLASS_READER_CONF;
|
result_status |= FLAG_ICLASS_READER_CONF;
|
||||||
|
memcpy(card_data+8, resp, 8);
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("Failed to dump config block");
|
Dbprintf("Failed to dump config block");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read block 5, AA
|
//Read block 5, AA
|
||||||
if(arg0 & FLAG_ICLASS_READER_AA){
|
if(flagReadAA) {
|
||||||
if(sendCmdGetResponseWithRetries(readAA, sizeof(readAA),card_data+(8*4), 10, 10))
|
if(sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, 10, 10))
|
||||||
{
|
{
|
||||||
result_status |= FLAG_ICLASS_READER_AA;
|
result_status |= FLAG_ICLASS_READER_AA;
|
||||||
|
memcpy(card_data+(8*5), resp, 8);
|
||||||
} else {
|
} else {
|
||||||
//Dbprintf("Failed to dump AA block");
|
//Dbprintf("Failed to dump AA block");
|
||||||
}
|
}
|
||||||
|
@ -1747,19 +1758,20 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
// (3,4 write-only, kc and kd)
|
// (3,4 write-only, kc and kd)
|
||||||
// 5 Application issuer area
|
// 5 Application issuer area
|
||||||
//
|
//
|
||||||
//Then we can 'ship' back the 8 * 5 bytes of data,
|
//Then we can 'ship' back the 8 * 6 bytes of data,
|
||||||
// with 0xFF:s in block 3 and 4.
|
// with 0xFF:s in block 3 and 4.
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
//Send back to client, but don't bother if we already sent this
|
//Send back to client, but don't bother if we already sent this -
|
||||||
|
// only useful if looping in arm (not try_once && not abort_after_read)
|
||||||
if(memcmp(last_csn, card_data, 8) != 0)
|
if(memcmp(last_csn, card_data, 8) != 0)
|
||||||
{
|
{
|
||||||
// If caller requires that we get CC, continue until we got it
|
// If caller requires that we get Conf, CC, AA, continue until we got it
|
||||||
if( (arg0 & read_status & FLAG_ICLASS_READER_CC) || !(arg0 & FLAG_ICLASS_READER_CC))
|
if( (result_status ^ FLAG_ICLASS_READER_CSN ^ flagReadConfig ^ flagReadCC ^ flagReadAA) == 0) {
|
||||||
{
|
|
||||||
cmd_send(CMD_ACK,result_status,0,0,card_data,sizeof(card_data));
|
cmd_send(CMD_ACK,result_status,0,0,card_data,sizeof(card_data));
|
||||||
if(abort_after_read) {
|
if(abort_after_read) {
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
|
LED_B_OFF();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Save that we already sent this....
|
//Save that we already sent this....
|
||||||
|
@ -1768,8 +1780,13 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
|
|
||||||
}
|
}
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
userCancelled = BUTTON_PRESS() || usb_poll_validate_length();
|
||||||
}
|
}
|
||||||
|
if (userCancelled) {
|
||||||
|
cmd_send(CMD_ACK,0xFF,0,0,card_data, 0);
|
||||||
|
} else {
|
||||||
cmd_send(CMD_ACK,0,0,0,card_data, 0);
|
cmd_send(CMD_ACK,0,0,0,card_data, 0);
|
||||||
|
}
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1179,6 +1179,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
// bit 2 - need HALT after sequence
|
// bit 2 - need HALT after sequence
|
||||||
// bit 3 - need init FPGA and field before sequence
|
// bit 3 - need init FPGA and field before sequence
|
||||||
// bit 4 - need reset FPGA and LED
|
// bit 4 - need reset FPGA and LED
|
||||||
|
// bit 6 - gen1b backdoor type
|
||||||
uint8_t workFlags = arg1;
|
uint8_t workFlags = arg1;
|
||||||
uint8_t blockNo = arg2;
|
uint8_t blockNo = arg2;
|
||||||
|
|
||||||
|
@ -1217,13 +1218,15 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
};
|
};
|
||||||
|
|
||||||
if(mifare_classic_halt(NULL, cuid)) {
|
if(mifare_classic_halt(NULL, cuid)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
if (MF_DBGLEVEL > 2) Dbprintf("Halt error");
|
||||||
break;
|
// Continue, some magic tags misbehavies and send an answer to it.
|
||||||
|
// break;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// reset chip
|
// reset chip
|
||||||
if (needWipe){
|
// Wipe command don't work with gen1b
|
||||||
|
if (needWipe && !(workFlags & 0x40)){
|
||||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
|
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
|
||||||
|
@ -1237,14 +1240,19 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
};
|
};
|
||||||
|
|
||||||
if(mifare_classic_halt(NULL, cuid)) {
|
if(mifare_classic_halt(NULL, cuid)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
if (MF_DBGLEVEL > 2) Dbprintf("Halt error");
|
||||||
break;
|
// Continue, some magic tags misbehavies and send an answer to it.
|
||||||
|
// break;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// write block
|
// write block
|
||||||
if (workFlags & 0x02) {
|
if (workFlags & 0x02) {
|
||||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||||
|
|
||||||
|
// gen1b magic tag : do no issue wupC2 and don't expect 0x0a response after SELECT_UID (after getting UID from chip in 'hf mf csetuid' command)
|
||||||
|
if (!(workFlags & 0x40)) {
|
||||||
|
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
|
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
|
||||||
break;
|
break;
|
||||||
|
@ -1256,6 +1264,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
|
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");
|
if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");
|
||||||
|
@ -1272,10 +1281,14 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
};
|
};
|
||||||
|
|
||||||
if (workFlags & 0x04) {
|
if (workFlags & 0x04) {
|
||||||
|
// do no issue halt command for gen1b magic tag (#db# halt error. response len: 1)
|
||||||
|
if (!(workFlags & 0x40)) {
|
||||||
if (mifare_classic_halt(NULL, cuid)) {
|
if (mifare_classic_halt(NULL, cuid)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
if (MF_DBGLEVEL > 2) Dbprintf("Halt error");
|
||||||
break;
|
// Continue, some magic tags misbehavies and send an answer to it.
|
||||||
};
|
// break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isOK = 1;
|
isOK = 1;
|
||||||
|
@ -1301,6 +1314,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
// bit 3 - need init FPGA and field before sequence
|
// bit 3 - need init FPGA and field before sequence
|
||||||
// bit 4 - need reset FPGA and LED
|
// bit 4 - need reset FPGA and LED
|
||||||
// bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
// bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
||||||
|
// bit 6 - gen1b backdoor type
|
||||||
uint8_t workFlags = arg0;
|
uint8_t workFlags = arg0;
|
||||||
uint8_t blockNo = arg2;
|
uint8_t blockNo = arg2;
|
||||||
|
|
||||||
|
@ -1333,13 +1347,15 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
|
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
// do no issue for gen1b magic tag
|
||||||
|
if (!(workFlags & 0x40)) {
|
||||||
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
|
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// read block
|
// read block
|
||||||
if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
|
if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
|
||||||
|
@ -1349,10 +1365,14 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
memcpy(data, receivedAnswer, 18);
|
memcpy(data, receivedAnswer, 18);
|
||||||
|
|
||||||
if (workFlags & 0x04) {
|
if (workFlags & 0x04) {
|
||||||
|
// do no issue halt command for gen1b magic tag (#db# halt error. response len: 1)
|
||||||
|
if (!(workFlags & 0x40)) {
|
||||||
if (mifare_classic_halt(NULL, cuid)) {
|
if (mifare_classic_halt(NULL, cuid)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
if (MF_DBGLEVEL > 1) Dbprintf("Halt error");
|
||||||
break;
|
// Continue, some magic tags misbehavies and send an answer to it.
|
||||||
};
|
// break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isOK = 1;
|
isOK = 1;
|
||||||
|
@ -1381,24 +1401,23 @@ void MifareCIdent(){
|
||||||
uint8_t wupC2[] = { 0x43 };
|
uint8_t wupC2[] = { 0x43 };
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
byte_t isOK = 1;
|
byte_t isOK = 0;
|
||||||
|
|
||||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(ReaderReceive(receivedAnswer, receivedAnswerPar) && (receivedAnswer[0] == 0x0a)) {
|
||||||
isOK = 0;
|
isOK = 2;
|
||||||
};
|
|
||||||
|
|
||||||
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(ReaderReceive(receivedAnswer, receivedAnswerPar) && (receivedAnswer[0] == 0x0a)) {
|
||||||
isOK = 0;
|
isOK = 1;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mifare_classic_halt(NULL, 0)) {
|
// From iceman1001: removed the if, since some magic tags misbehavies and send an answer to it.
|
||||||
isOK = 0;
|
mifare_classic_halt(NULL, 0);
|
||||||
};
|
|
||||||
|
|
||||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@ RM = rm -f
|
||||||
MV = mv
|
MV = mv
|
||||||
|
|
||||||
#COMMON_FLAGS = -m32
|
#COMMON_FLAGS = -m32
|
||||||
VPATH = ../common ../zlib
|
VPATH = ../common ../zlib ../uart
|
||||||
OBJDIR = obj
|
OBJDIR = obj
|
||||||
|
|
||||||
LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
|
LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
|
||||||
LUALIB = ../liblua/liblua.a
|
LUALIB = ../liblua/liblua.a
|
||||||
LDFLAGS = $(COMMON_FLAGS)
|
LDFLAGS = $(COMMON_FLAGS)
|
||||||
CFLAGS = -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O3
|
CFLAGS = -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../zlib -I../uart -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O3
|
||||||
CXXFLAGS = -I../include -Wall -O3
|
CXXFLAGS = -I../include -Wall -O3
|
||||||
|
|
||||||
LUAPLATFORM = generic
|
LUAPLATFORM = generic
|
||||||
|
@ -78,7 +78,8 @@ DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
||||||
# make temporary to final dependeny files after successful compilation
|
# make temporary to final dependeny files after successful compilation
|
||||||
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d
|
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d
|
||||||
|
|
||||||
CORESRCS = uart.c \
|
CORESRCS = uart_posix.c \
|
||||||
|
uart_win32.c \
|
||||||
util.c \
|
util.c \
|
||||||
util_posix.c
|
util_posix.c
|
||||||
|
|
||||||
|
@ -139,6 +140,7 @@ CMDSRCS = crapto1/crapto1.c\
|
||||||
cmdlfti.c \
|
cmdlfti.c \
|
||||||
cmdlfviking.c\
|
cmdlfviking.c\
|
||||||
cmdlfvisa2000.c\
|
cmdlfvisa2000.c\
|
||||||
|
cmdlfpac.c\
|
||||||
cmdparser.c \
|
cmdparser.c \
|
||||||
cmdmain.c \
|
cmdmain.c \
|
||||||
scripting.c\
|
scripting.c\
|
||||||
|
@ -209,8 +211,8 @@ all-static: LDLIBS:=-static $(LDLIBS)
|
||||||
all-static: proxmark3 flasher fpga_compress
|
all-static: proxmark3 flasher fpga_compress
|
||||||
|
|
||||||
proxmark3: LDLIBS+=$(LUALIB) $(QTLDLIBS)
|
proxmark3: LDLIBS+=$(LUALIB) $(QTLDLIBS)
|
||||||
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) lualibs/usb_cmd.lua
|
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) lualibs/usb_cmd.lua
|
||||||
$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@
|
$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(LDLIBS) -o $@
|
||||||
|
|
||||||
flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS)
|
flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS)
|
||||||
$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
205
client/cmddata.c
205
client/cmddata.c
|
@ -1234,6 +1234,7 @@ int getSamples(int n, bool silent)
|
||||||
}
|
}
|
||||||
|
|
||||||
setClockGrid(0,0);
|
setClockGrid(0,0);
|
||||||
|
DemodBufferLen = 0;
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1338,6 +1339,7 @@ int CmdLoad(const char *Cmd)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLog("loaded %d samples", GraphTraceLen);
|
PrintAndLog("loaded %d samples", GraphTraceLen);
|
||||||
setClockGrid(0,0);
|
setClockGrid(0,0);
|
||||||
|
DemodBufferLen = 0;
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1395,8 +1397,7 @@ int CmdNorm(const char *Cmd)
|
||||||
|
|
||||||
if (max != min) {
|
if (max != min) {
|
||||||
for (i = 0; i < GraphTraceLen; ++i) {
|
for (i = 0; i < GraphTraceLen; ++i) {
|
||||||
GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 /
|
GraphBuffer[i] = ((long)(GraphBuffer[i] - ((max + min) / 2)) * 256) / (max - min);
|
||||||
(max - min);
|
|
||||||
//marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work
|
//marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1606,6 +1607,205 @@ int Cmdhex2bin(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* // example of FSK2 RF/50 Tones
|
||||||
|
static const int LowTone[] = {
|
||||||
|
1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, 1, -1, -1, -1, -1, -1
|
||||||
|
};
|
||||||
|
static const int HighTone[] = {
|
||||||
|
1, 1, 1, 1, 1, -1, -1, -1, -1, // note one extra 1 to padd due to 50/8 remainder (1/2 the remainder)
|
||||||
|
1, 1, 1, 1, -1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, -1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, -1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, -1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, -1, -1, -1, -1, -1, // note one extra -1 to padd due to 50/8 remainder
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
void GetHiLoTone(int *LowTone, int *HighTone, int clk, int LowToneFC, int HighToneFC) {
|
||||||
|
int i,j=0;
|
||||||
|
int Left_Modifier = ((clk % LowToneFC) % 2) + ((clk % LowToneFC)/2);
|
||||||
|
int Right_Modifier = (clk % LowToneFC) / 2;
|
||||||
|
//int HighToneMod = clk mod HighToneFC;
|
||||||
|
int LeftHalfFCCnt = (LowToneFC % 2) + (LowToneFC/2); //truncate
|
||||||
|
int FCs_per_clk = clk/LowToneFC;
|
||||||
|
|
||||||
|
// need to correctly split up the clock to field clocks.
|
||||||
|
// First attempt uses modifiers on each end to make up for when FCs don't evenly divide into Clk
|
||||||
|
|
||||||
|
// start with LowTone
|
||||||
|
// set extra 1 modifiers to make up for when FC doesn't divide evenly into Clk
|
||||||
|
for (i = 0; i < Left_Modifier; i++) {
|
||||||
|
LowTone[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop # of field clocks inside the main clock
|
||||||
|
for (i = 0; i < (FCs_per_clk); i++) {
|
||||||
|
// loop # of samples per field clock
|
||||||
|
for (j = 0; j < LowToneFC; j++) {
|
||||||
|
LowTone[(i*LowToneFC)+Left_Modifier+j] = ( j < LeftHalfFCCnt ) ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int k;
|
||||||
|
// add last -1 modifiers
|
||||||
|
for (k = 0; k < Right_Modifier; k++) {
|
||||||
|
LowTone[((i-1)*LowToneFC)+Left_Modifier+j+k] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now do hightone
|
||||||
|
Left_Modifier = ((clk % HighToneFC) % 2) + ((clk % HighToneFC)/2);
|
||||||
|
Right_Modifier = (clk % HighToneFC) / 2;
|
||||||
|
LeftHalfFCCnt = (HighToneFC % 2) + (HighToneFC/2); //truncate
|
||||||
|
FCs_per_clk = clk/HighToneFC;
|
||||||
|
|
||||||
|
for (i = 0; i < Left_Modifier; i++) {
|
||||||
|
HighTone[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop # of field clocks inside the main clock
|
||||||
|
for (i = 0; i < (FCs_per_clk); i++) {
|
||||||
|
// loop # of samples per field clock
|
||||||
|
for (j = 0; j < HighToneFC; j++) {
|
||||||
|
HighTone[(i*HighToneFC)+Left_Modifier+j] = ( j < LeftHalfFCCnt ) ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add last -1 modifiers
|
||||||
|
for (k = 0; k < Right_Modifier; k++) {
|
||||||
|
PrintAndLog("(i-1)*HighToneFC+lm+j+k %i",((i-1)*HighToneFC)+Left_Modifier+j+k);
|
||||||
|
HighTone[((i-1)*HighToneFC)+Left_Modifier+j+k] = -1;
|
||||||
|
}
|
||||||
|
if (g_debugMode == 2) {
|
||||||
|
for ( i = 0; i < clk; i++) {
|
||||||
|
PrintAndLog("Low: %i, High: %i",LowTone[i],HighTone[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//old CmdFSKdemod adapted by marshmellow
|
||||||
|
//converts FSK to clear NRZ style wave. (or demodulates)
|
||||||
|
int FSKToNRZ(int *data, int *dataLen, int clk, int LowToneFC, int HighToneFC) {
|
||||||
|
uint8_t ans=0;
|
||||||
|
if (clk == 0 || LowToneFC == 0 || HighToneFC == 0) {
|
||||||
|
int firstClockEdge=0;
|
||||||
|
ans = fskClocks((uint8_t *) &LowToneFC, (uint8_t *) &HighToneFC, (uint8_t *) &clk, false, &firstClockEdge);
|
||||||
|
if (g_debugMode > 1) {
|
||||||
|
PrintAndLog ("DEBUG FSKtoNRZ: detected clocks: fc_low %i, fc_high %i, clk %i, firstClockEdge %i, ans %u", LowToneFC, HighToneFC, clk, firstClockEdge, ans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// currently only know fsk modulations with field clocks < 10 samples and > 4 samples. filter out to remove false positives (and possibly destroying ask/psk modulated waves...)
|
||||||
|
if (ans == 0 || clk == 0 || LowToneFC == 0 || HighToneFC == 0 || LowToneFC > 10 || HighToneFC < 4) {
|
||||||
|
if (g_debugMode > 1) {
|
||||||
|
PrintAndLog ("DEBUG FSKtoNRZ: no fsk clocks found");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int LowTone[clk];
|
||||||
|
int HighTone[clk];
|
||||||
|
GetHiLoTone(LowTone, HighTone, clk, LowToneFC, HighToneFC);
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
// loop through ([all samples] - clk)
|
||||||
|
for (i = 0; i < *dataLen - clk; ++i) {
|
||||||
|
int lowSum = 0, highSum = 0;
|
||||||
|
|
||||||
|
// sum all samples together starting from this sample for [clk] samples for each tone (multiply tone value with sample data)
|
||||||
|
for (j = 0; j < clk; ++j) {
|
||||||
|
lowSum += LowTone[j] * data[i+j];
|
||||||
|
highSum += HighTone[j] * data[i + j];
|
||||||
|
}
|
||||||
|
// get abs( [average sample value per clk] * 100 ) (or a rolling average of sorts)
|
||||||
|
lowSum = abs(100 * lowSum / clk);
|
||||||
|
highSum = abs(100 * highSum / clk);
|
||||||
|
// save these back to buffer for later use
|
||||||
|
data[i] = (highSum << 16) | lowSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we have the abs( [average sample value per clk] * 100 ) for each tone
|
||||||
|
// loop through again [all samples] - clk - 16
|
||||||
|
// note why 16??? is 16 the largest FC? changed to LowToneFC as that should be the > fc
|
||||||
|
for(i = 0; i < *dataLen - clk - LowToneFC; ++i) {
|
||||||
|
int lowTot = 0, highTot = 0;
|
||||||
|
|
||||||
|
// sum a field clock width of abs( [average sample values per clk] * 100) for each tone
|
||||||
|
for (j = 0; j < LowToneFC; ++j) { //10 for fsk2
|
||||||
|
lowTot += (data[i + j] & 0xffff);
|
||||||
|
}
|
||||||
|
for (j = 0; j < HighToneFC; j++) { //8 for fsk2
|
||||||
|
highTot += (data[i + j] >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// subtract the sum of lowTone averages by the sum of highTone averages as it
|
||||||
|
// and write back the new graph value
|
||||||
|
data[i] = lowTot - highTot;
|
||||||
|
}
|
||||||
|
// update dataLen to what we put back to the data sample buffer
|
||||||
|
*dataLen -= (clk + LowToneFC);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usage_data_fsktonrz() {
|
||||||
|
PrintAndLog("Usage: data fsktonrz c <clock> l <fc_low> f <fc_high>");
|
||||||
|
PrintAndLog("Options: ");
|
||||||
|
PrintAndLog(" h This help");
|
||||||
|
PrintAndLog(" c <clock> enter the a clock (omit to autodetect)");
|
||||||
|
PrintAndLog(" l <fc_low> enter a field clock (omit to autodetect)");
|
||||||
|
PrintAndLog(" f <fc_high> enter a field clock (omit to autodetect)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdFSKToNRZ(const char *Cmd) {
|
||||||
|
// take clk, fc_low, fc_high
|
||||||
|
// blank = auto;
|
||||||
|
bool errors = false;
|
||||||
|
int clk = 0;
|
||||||
|
char cmdp = 0;
|
||||||
|
int fc_low = 10, fc_high = 8;
|
||||||
|
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||||
|
{
|
||||||
|
switch(param_getchar(Cmd, cmdp))
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
return usage_data_fsktonrz();
|
||||||
|
case 'C':
|
||||||
|
case 'c':
|
||||||
|
clk = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
case 'f':
|
||||||
|
fc_high = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
case 'l':
|
||||||
|
fc_low = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(errors) break;
|
||||||
|
}
|
||||||
|
//Validations
|
||||||
|
if(errors) return usage_data_fsktonrz();
|
||||||
|
|
||||||
|
setClockGrid(0,0);
|
||||||
|
DemodBufferLen = 0;
|
||||||
|
int ans = FSKToNRZ(GraphBuffer, &GraphTraceLen, clk, fc_low, fc_high);
|
||||||
|
CmdNorm("");
|
||||||
|
RepaintGraphWindow();
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static command_t CommandTable[] =
|
static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
|
@ -1617,6 +1817,7 @@ static command_t CommandTable[] =
|
||||||
{"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
|
{"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
|
||||||
{"dec", CmdDec, 1, "Decimate samples"},
|
{"dec", CmdDec, 1, "Decimate samples"},
|
||||||
{"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
|
{"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
|
||||||
|
{"fsktonrz", CmdFSKToNRZ, 1, "Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk)"},
|
||||||
{"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
|
{"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
|
||||||
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
|
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
|
||||||
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
|
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
|
||||||
|
|
|
@ -673,16 +673,17 @@ int CmdHFSearch(const char *Cmd){
|
||||||
PrintAndLog("\nValid iClass Tag (or PicoPass Tag) Found - Quiting Search\n");
|
PrintAndLog("\nValid iClass Tag (or PicoPass Tag) Found - Quiting Search\n");
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
ans = HF14BInfo(false);
|
|
||||||
if (ans) {
|
|
||||||
PrintAndLog("\nValid ISO14443B Tag Found - Quiting Search\n");
|
|
||||||
return ans;
|
|
||||||
}
|
|
||||||
ans = HF15Reader("", false);
|
ans = HF15Reader("", false);
|
||||||
if (ans) {
|
if (ans) {
|
||||||
PrintAndLog("\nValid ISO15693 Tag Found - Quiting Search\n");
|
PrintAndLog("\nValid ISO15693 Tag Found - Quiting Search\n");
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
//14b is longest test currently (and rarest chip type) ... put last
|
||||||
|
ans = HF14BInfo(false);
|
||||||
|
if (ans) {
|
||||||
|
PrintAndLog("\nValid ISO14443B Tag Found - Quiting Search\n");
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
PrintAndLog("\nno known/supported 13.56 MHz tags found\n");
|
PrintAndLog("\nno known/supported 13.56 MHz tags found\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
#include "mifare.h"
|
#include "mifare.h"
|
||||||
#include "cmdhfmfu.h"
|
#include "cmdhfmfu.h"
|
||||||
|
#include "mifarehost.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
static void waitCmd(uint8_t iLen);
|
static void waitCmd(uint8_t iLen);
|
||||||
|
@ -410,8 +411,13 @@ int CmdHF14AReader(const char *Cmd)
|
||||||
c.arg[2] = 0;
|
c.arg[2] = 0;
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
WaitForResponse(CMD_ACK,&resp);
|
WaitForResponse(CMD_ACK,&resp);
|
||||||
uint8_t isOK = resp.arg[0] & 0xff;
|
|
||||||
PrintAndLog("Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
|
uint8_t isGeneration = resp.arg[0] & 0xff;
|
||||||
|
switch( isGeneration ){
|
||||||
|
case 1: PrintAndLog("Answers to chinese magic backdoor commands (GEN 1a): YES"); break;
|
||||||
|
case 2: PrintAndLog("Answers to chinese magic backdoor commands (GEN 1b): YES"); break;
|
||||||
|
default: PrintAndLog("Answers to chinese magic backdoor commands: NO"); break;
|
||||||
|
}
|
||||||
|
|
||||||
// disconnect
|
// disconnect
|
||||||
c.cmd = CMD_READER_ISO_14443a;
|
c.cmd = CMD_READER_ISO_14443a;
|
||||||
|
|
|
@ -180,10 +180,10 @@ int CmdHFiClassSim(const char *Cmd) {
|
||||||
|
|
||||||
int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
|
int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
|
||||||
bool tagFound = false;
|
bool tagFound = false;
|
||||||
UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN|
|
UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN |
|
||||||
FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_AA}};
|
FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_CONF | FLAG_ICLASS_READER_AA |
|
||||||
|
FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_ONE_TRY } };
|
||||||
// loop in client not device - else on windows have a communication error
|
// loop in client not device - else on windows have a communication error
|
||||||
c.arg[0] |= FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_ONE_TRY;
|
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
while(!ukbhit()){
|
while(!ukbhit()){
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
@ -191,27 +191,28 @@ int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
|
||||||
uint8_t readStatus = resp.arg[0] & 0xff;
|
uint8_t readStatus = resp.arg[0] & 0xff;
|
||||||
uint8_t *data = resp.d.asBytes;
|
uint8_t *data = resp.d.asBytes;
|
||||||
|
|
||||||
if (verbose)
|
// no tag found or button pressed
|
||||||
PrintAndLog("Readstatus:%02x", readStatus);
|
if( (readStatus == 0 && !loop) || readStatus == 0xFF) {
|
||||||
if( readStatus == 0){
|
// abort
|
||||||
//Aborted
|
|
||||||
if (verbose) PrintAndLog("Quitting...");
|
if (verbose) PrintAndLog("Quitting...");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if( readStatus & FLAG_ICLASS_READER_CSN){
|
|
||||||
|
if( readStatus & FLAG_ICLASS_READER_CSN) {
|
||||||
PrintAndLog(" CSN: %s",sprint_hex(data,8));
|
PrintAndLog(" CSN: %s",sprint_hex(data,8));
|
||||||
tagFound = true;
|
tagFound = true;
|
||||||
}
|
}
|
||||||
if( readStatus & FLAG_ICLASS_READER_CC) PrintAndLog(" CC: %s",sprint_hex(data+16,8));
|
if( readStatus & FLAG_ICLASS_READER_CC) {
|
||||||
if( readStatus & FLAG_ICLASS_READER_CONF){
|
PrintAndLog(" CC: %s",sprint_hex(data+16,8));
|
||||||
|
}
|
||||||
|
if( readStatus & FLAG_ICLASS_READER_CONF) {
|
||||||
printIclassDumpInfo(data);
|
printIclassDumpInfo(data);
|
||||||
}
|
}
|
||||||
//TODO add iclass read block 05 and test iclass type..
|
|
||||||
if (readStatus & FLAG_ICLASS_READER_AA) {
|
if (readStatus & FLAG_ICLASS_READER_AA) {
|
||||||
bool legacy = true;
|
bool legacy = true;
|
||||||
PrintAndLog(" AppIA: %s",sprint_hex(data+8*4,8));
|
PrintAndLog(" AppIA: %s",sprint_hex(data+8*5,8));
|
||||||
for (int i = 0; i<8; i++) {
|
for (int i = 0; i<8; i++) {
|
||||||
if (data[8*4+i] != 0xFF) {
|
if (data[8*5+i] != 0xFF) {
|
||||||
legacy = false;
|
legacy = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1711,7 +1712,7 @@ static command_t CommandTable[] =
|
||||||
{"loclass", CmdHFiClass_loclass, 1, "[options..] Use loclass to perform bruteforce of reader attack dump"},
|
{"loclass", CmdHFiClass_loclass, 1, "[options..] Use loclass to perform bruteforce of reader attack dump"},
|
||||||
{"managekeys", CmdHFiClassManageKeys, 1, "[options..] Manage the keys to use with iClass"},
|
{"managekeys", CmdHFiClassManageKeys, 1, "[options..] Manage the keys to use with iClass"},
|
||||||
{"readblk", CmdHFiClass_ReadBlock, 0, "[options..] Authenticate and Read iClass block"},
|
{"readblk", CmdHFiClass_ReadBlock, 0, "[options..] Authenticate and Read iClass block"},
|
||||||
{"reader", CmdHFiClassReader, 0, " Read an iClass tag"},
|
{"reader", CmdHFiClassReader, 0, " Look for iClass tags until a key or the pm3 button is pressed"},
|
||||||
{"readtagfile", CmdHFiClassReadTagFile, 1, "[options..] Display Content from tagfile"},
|
{"readtagfile", CmdHFiClassReadTagFile, 1, "[options..] Display Content from tagfile"},
|
||||||
{"replay", CmdHFiClassReader_Replay, 0, "<mac> Read an iClass tag via Reply Attack"},
|
{"replay", CmdHFiClassReader_Replay, 0, "<mac> Read an iClass tag via Reply Attack"},
|
||||||
{"sim", CmdHFiClassSim, 0, "[options..] Simulate iClass tag"},
|
{"sim", CmdHFiClassSim, 0, "[options..] Simulate iClass tag"},
|
||||||
|
|
159
client/cmdhfmf.c
159
client/cmdhfmf.c
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#define NESTED_SECTOR_RETRY 10 // how often we try mfested() until we give up
|
#define NESTED_SECTOR_RETRY 10 // how often we try mfested() until we give up
|
||||||
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
int CmdHF14AMifare(const char *Cmd)
|
int CmdHF14AMifare(const char *Cmd)
|
||||||
|
@ -1738,7 +1737,6 @@ int CmdHF14AMfECFill(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CmdHF14AMfEKeyPrn(const char *Cmd)
|
int CmdHF14AMfEKeyPrn(const char *Cmd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1783,7 +1781,6 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CmdHF14AMfCSetUID(const char *Cmd)
|
int CmdHF14AMfCSetUID(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t wipeCard = 0;
|
uint8_t wipeCard = 0;
|
||||||
|
@ -1858,7 +1855,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||||
uint8_t memBlock[16] = {0x00};
|
uint8_t memBlock[16] = {0x00};
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
bool wipeCard = false;
|
bool wipeCard = false;
|
||||||
int res;
|
int res, gen = 0;
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||||
PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)> [w]");
|
PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)> [w]");
|
||||||
|
@ -1868,6 +1865,8 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gen = mfCIdentify();
|
||||||
|
|
||||||
blockNo = param_get8(Cmd, 0);
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
|
||||||
if (param_gethex(Cmd, 1, memBlock, 32)) {
|
if (param_gethex(Cmd, 1, memBlock, 32)) {
|
||||||
|
@ -1879,7 +1878,14 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||||
wipeCard = (ctmp == 'w' || ctmp == 'W');
|
wipeCard = (ctmp == 'w' || ctmp == 'W');
|
||||||
PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));
|
PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));
|
||||||
|
|
||||||
|
if (gen == 2) {
|
||||||
|
/* generation 1b magic card */
|
||||||
|
res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER | CSETBLOCK_MAGIC_1B);
|
||||||
|
} else {
|
||||||
|
/* generation 1a magic card by default */
|
||||||
res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER);
|
res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER);
|
||||||
|
}
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLog("Can't write block. error=%d", res);
|
PrintAndLog("Can't write block. error=%d", res);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1893,33 +1899,44 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
FILE * f;
|
FILE * f;
|
||||||
char filename[FILE_PATH_SIZE] = {0x00};
|
char filename[FILE_PATH_SIZE] = {0x00};
|
||||||
char * fnameptr = filename;
|
char * fnameptr = filename;
|
||||||
char buf[64] = {0x00};
|
char buf[256] = {0x00};
|
||||||
uint8_t buf8[64] = {0x00};
|
uint8_t buf8[256] = {0x00};
|
||||||
uint8_t fillFromEmulator = 0;
|
uint8_t fillFromEmulator = 0;
|
||||||
int i, len, blockNum, flags=0;
|
int i, len, blockNum, flags = 0, gen = 0, numblock = 64;
|
||||||
|
|
||||||
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
|
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
|
||||||
PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
|
PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
|
||||||
PrintAndLog("or from emulator memory (option `e`)");
|
PrintAndLog("or from emulator memory (option `e`). 4K card: (option `4`)");
|
||||||
PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>");
|
PrintAndLog("Usage: hf mf cload [file name w/o `.eml`][e][4]");
|
||||||
PrintAndLog(" or: hf mf cload e ");
|
PrintAndLog(" or: hf mf cload e [4]");
|
||||||
PrintAndLog(" sample: hf mf cload filename");
|
PrintAndLog("Sample: hf mf cload filename");
|
||||||
|
PrintAndLog(" hf mf cload filname 4");
|
||||||
|
PrintAndLog(" hf mf cload e");
|
||||||
|
PrintAndLog(" hf mf cload e 4");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char ctmp = param_getchar(Cmd, 0);
|
char ctmp = param_getchar(Cmd, 0);
|
||||||
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
|
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
|
||||||
|
ctmp = param_getchar(Cmd, 1);
|
||||||
|
if (ctmp == '4') numblock = 256;
|
||||||
|
|
||||||
|
gen = mfCIdentify();
|
||||||
|
PrintAndLog("Loading magic mifare %dK", numblock == 256 ? 4:1);
|
||||||
|
|
||||||
if (fillFromEmulator) {
|
if (fillFromEmulator) {
|
||||||
for (blockNum = 0; blockNum < 16 * 4; blockNum += 1) {
|
for (blockNum = 0; blockNum < numblock; blockNum += 1) {
|
||||||
if (mfEmlGetMem(buf8, blockNum, 1)) {
|
if (mfEmlGetMem(buf8, blockNum, 1)) {
|
||||||
PrintAndLog("Cant get block: %d", blockNum);
|
PrintAndLog("Cant get block: %d", blockNum);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence
|
if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence
|
||||||
if (blockNum == 1) flags = 0; // just write
|
if (blockNum == 1) flags = 0; // just write
|
||||||
if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Magic Halt and switch off field.
|
if (blockNum == numblock - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Magic Halt and switch off field.
|
||||||
|
|
||||||
|
if (gen == 2)
|
||||||
|
/* generation 1b magic card */
|
||||||
|
flags |= CSETBLOCK_MAGIC_1B;
|
||||||
if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
|
if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
|
||||||
PrintAndLog("Cant set magic card block: %d", blockNum);
|
PrintAndLog("Cant set magic card block: %d", blockNum);
|
||||||
return 3;
|
return 3;
|
||||||
|
@ -1927,10 +1944,12 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
len = strlen(Cmd);
|
param_getstr(Cmd, 0, filename);
|
||||||
|
|
||||||
|
len = strlen(filename);
|
||||||
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
|
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
|
||||||
|
|
||||||
memcpy(filename, Cmd, len);
|
//memcpy(filename, Cmd, len);
|
||||||
fnameptr += len;
|
fnameptr += len;
|
||||||
|
|
||||||
sprintf(fnameptr, ".eml");
|
sprintf(fnameptr, ".eml");
|
||||||
|
@ -1965,8 +1984,11 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
|
|
||||||
if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence
|
if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence
|
||||||
if (blockNum == 1) flags = 0; // just write
|
if (blockNum == 1) flags = 0; // just write
|
||||||
if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Switch off field.
|
if (blockNum == numblock - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Switch off field.
|
||||||
|
|
||||||
|
if (gen == 2)
|
||||||
|
/* generation 1b magic card */
|
||||||
|
flags |= CSETBLOCK_MAGIC_1B;
|
||||||
if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
|
if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
|
||||||
PrintAndLog("Can't set magic card block: %d", blockNum);
|
PrintAndLog("Can't set magic card block: %d", blockNum);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -1974,12 +1996,13 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
}
|
}
|
||||||
blockNum++;
|
blockNum++;
|
||||||
|
|
||||||
if (blockNum >= 16 * 4) break; // magic card type - mifare 1K
|
if (blockNum >= numblock) break; // magic card type - mifare 1K 64 blocks, mifare 4k 256 blocks
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
|
//if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
|
||||||
PrintAndLog("File content error. There must be 64 blocks");
|
if (blockNum != numblock){
|
||||||
|
PrintAndLog("File content error. There must be %d blocks", numblock);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
PrintAndLog("Loaded from file: %s", filename);
|
PrintAndLog("Loaded from file: %s", filename);
|
||||||
|
@ -1991,7 +2014,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
int CmdHF14AMfCGetBlk(const char *Cmd) {
|
int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||||
uint8_t memBlock[16];
|
uint8_t memBlock[16];
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
int res;
|
int res, gen = 0;
|
||||||
memset(memBlock, 0x00, sizeof(memBlock));
|
memset(memBlock, 0x00, sizeof(memBlock));
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||||
|
@ -2001,11 +2024,19 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gen = mfCIdentify();
|
||||||
|
|
||||||
blockNo = param_get8(Cmd, 0);
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
|
||||||
PrintAndLog("--block number:%2d ", blockNo);
|
PrintAndLog("--block number:%2d ", blockNo);
|
||||||
|
|
||||||
|
if (gen == 2) {
|
||||||
|
/* generation 1b magic card */
|
||||||
|
res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER | CSETBLOCK_MAGIC_1B);
|
||||||
|
} else {
|
||||||
|
/* generation 1a magic card by default */
|
||||||
res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER);
|
res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER);
|
||||||
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLog("Can't read block. error=%d", res);
|
PrintAndLog("Can't read block. error=%d", res);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2015,11 +2046,10 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CmdHF14AMfCGetSc(const char *Cmd) {
|
int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||||
uint8_t memBlock[16] = {0x00};
|
uint8_t memBlock[16] = {0x00};
|
||||||
uint8_t sectorNo = 0;
|
uint8_t sectorNo = 0;
|
||||||
int i, res, flags;
|
int i, res, flags, gen = 0, baseblock = 0, sect_size = 4;
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||||
PrintAndLog("Usage: hf mf cgetsc <sector number>");
|
PrintAndLog("Usage: hf mf cgetsc <sector number>");
|
||||||
|
@ -2029,25 +2059,40 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sectorNo = param_get8(Cmd, 0);
|
sectorNo = param_get8(Cmd, 0);
|
||||||
if (sectorNo > 15) {
|
|
||||||
PrintAndLog("Sector number must be in [0..15] as in MIFARE classic.");
|
if (sectorNo > 39) {
|
||||||
|
PrintAndLog("Sector number must be in [0..15] in MIFARE classic 1k and [0..39] in MIFARE classic 4k.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("--sector number:%d ", sectorNo);
|
PrintAndLog("--sector number:%d ", sectorNo);
|
||||||
|
|
||||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
gen = mfCIdentify();
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (i == 1) flags = 0;
|
|
||||||
if (i == 3) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
|
||||||
|
|
||||||
res = mfCGetBlock(sectorNo * 4 + i, memBlock, flags);
|
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
||||||
|
if (sectorNo < 32 ) {
|
||||||
|
baseblock = sectorNo * 4;
|
||||||
|
} else {
|
||||||
|
baseblock = 128 + 16 * (sectorNo - 32);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (sectorNo > 31) sect_size = 16;
|
||||||
|
|
||||||
|
for (i = 0; i < sect_size; i++) {
|
||||||
|
if (i == 1) flags = 0;
|
||||||
|
if (i == sect_size - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
||||||
|
|
||||||
|
if (gen == 2)
|
||||||
|
/* generation 1b magic card */
|
||||||
|
flags |= CSETBLOCK_MAGIC_1B;
|
||||||
|
|
||||||
|
res = mfCGetBlock(baseblock + i, memBlock, flags);
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res);
|
PrintAndLog("Can't read block. %d error=%d", baseblock + i, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("block %3d data:%s", sectorNo * 4 + i, sprint_hex(memBlock, 16));
|
PrintAndLog("block %3d data:%s", baseblock + i, sprint_hex(memBlock, 16));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2059,31 +2104,44 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
char filename[FILE_PATH_SIZE] = {0x00};
|
char filename[FILE_PATH_SIZE] = {0x00};
|
||||||
char * fnameptr = filename;
|
char * fnameptr = filename;
|
||||||
uint8_t fillFromEmulator = 0;
|
uint8_t fillFromEmulator = 0;
|
||||||
uint8_t buf[64] = {0x00};
|
uint8_t buf[256] = {0x00};
|
||||||
int i, j, len, flags;
|
int i, j, len, flags, gen = 0, numblock = 64;
|
||||||
|
|
||||||
// memset(filename, 0, sizeof(filename));
|
// memset(filename, 0, sizeof(filename));
|
||||||
// memset(buf, 0, sizeof(buf));
|
// memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
if (param_getchar(Cmd, 0) == 'h') {
|
if (param_getchar(Cmd, 0) == 'h') {
|
||||||
PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");
|
PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");
|
||||||
PrintAndLog("or into emulator memory (option `e`)");
|
PrintAndLog("or into emulator memory (option `e`). 4K card: (option `4`)");
|
||||||
PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]");
|
PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e][4]");
|
||||||
PrintAndLog(" sample: hf mf esave ");
|
PrintAndLog("Sample: hf mf esave ");
|
||||||
PrintAndLog(" hf mf esave filename");
|
PrintAndLog(" hf mf esave filename");
|
||||||
PrintAndLog(" hf mf esave e \n");
|
PrintAndLog(" hf mf esave e");
|
||||||
|
PrintAndLog(" hf mf esave 4");
|
||||||
|
PrintAndLog(" hf mf esave filename 4");
|
||||||
|
PrintAndLog(" hf mf esave e 4");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char ctmp = param_getchar(Cmd, 0);
|
char ctmp = param_getchar(Cmd, 0);
|
||||||
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
|
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
|
||||||
|
if (ctmp == '4') numblock = 256;
|
||||||
|
ctmp = param_getchar(Cmd, 1);
|
||||||
|
if (ctmp == '4') numblock = 256;
|
||||||
|
|
||||||
|
gen = mfCIdentify();
|
||||||
|
PrintAndLog("Saving magic mifare %dK", numblock == 256 ? 4:1);
|
||||||
|
|
||||||
if (fillFromEmulator) {
|
if (fillFromEmulator) {
|
||||||
// put into emulator
|
// put into emulator
|
||||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
||||||
for (i = 0; i < 16 * 4; i++) {
|
for (i = 0; i < numblock; i++) {
|
||||||
if (i == 1) flags = 0;
|
if (i == 1) flags = 0;
|
||||||
if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
if (i == numblock - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
||||||
|
|
||||||
|
if (gen == 2)
|
||||||
|
/* generation 1b magic card */
|
||||||
|
flags |= CSETBLOCK_MAGIC_1B;
|
||||||
|
|
||||||
if (mfCGetBlock(i, buf, flags)) {
|
if (mfCGetBlock(i, buf, flags)) {
|
||||||
PrintAndLog("Cant get block: %d", i);
|
PrintAndLog("Cant get block: %d", i);
|
||||||
|
@ -2097,12 +2155,20 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
len = strlen(Cmd);
|
param_getstr(Cmd, 0, filename);
|
||||||
|
|
||||||
|
len = strlen(filename);
|
||||||
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
|
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
|
||||||
|
|
||||||
if (len < 1) {
|
ctmp = param_getchar(Cmd, 0);
|
||||||
|
if (len < 1 || (ctmp == '4')) {
|
||||||
// get filename
|
// get filename
|
||||||
if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) {
|
|
||||||
|
flags = CSETBLOCK_SINGLE_OPER;
|
||||||
|
if (gen == 2)
|
||||||
|
/* generation 1b magic card */
|
||||||
|
flags |= CSETBLOCK_MAGIC_1B;
|
||||||
|
if (mfCGetBlock(0, buf, flags)) {
|
||||||
PrintAndLog("Cant get block: %d", 0);
|
PrintAndLog("Cant get block: %d", 0);
|
||||||
len = sprintf(fnameptr, "dump");
|
len = sprintf(fnameptr, "dump");
|
||||||
fnameptr += len;
|
fnameptr += len;
|
||||||
|
@ -2112,7 +2178,7 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
sprintf(fnameptr, "%02x", buf[j]);
|
sprintf(fnameptr, "%02x", buf[j]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
memcpy(filename, Cmd, len);
|
//memcpy(filename, Cmd, len);
|
||||||
fnameptr += len;
|
fnameptr += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2128,10 +2194,13 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
|
|
||||||
// put hex
|
// put hex
|
||||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
||||||
for (i = 0; i < 16 * 4; i++) {
|
for (i = 0; i < numblock; i++) {
|
||||||
if (i == 1) flags = 0;
|
if (i == 1) flags = 0;
|
||||||
if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
if (i == numblock - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
||||||
|
|
||||||
|
if (gen == 2)
|
||||||
|
/* generation 1b magic card */
|
||||||
|
flags |= CSETBLOCK_MAGIC_1B;
|
||||||
if (mfCGetBlock(i, buf, flags)) {
|
if (mfCGetBlock(i, buf, flags)) {
|
||||||
PrintAndLog("Cant get block: %d", i);
|
PrintAndLog("Cant get block: %d", i);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "parity.h"
|
#include "parity.h"
|
||||||
#include "hardnested/hardnested_bruteforce.h"
|
#include "hardnested/hardnested_bruteforce.h"
|
||||||
#include "hardnested/hardnested_bitarray_core.h"
|
#include "hardnested/hardnested_bitarray_core.h"
|
||||||
|
#include "zlib.h"
|
||||||
|
|
||||||
#define NUM_CHECK_BITFLIPS_THREADS (num_CPUs())
|
#define NUM_CHECK_BITFLIPS_THREADS (num_CPUs())
|
||||||
#define NUM_REDUCTION_WORKING_THREADS (num_CPUs())
|
#define NUM_REDUCTION_WORKING_THREADS (num_CPUs())
|
||||||
|
@ -40,7 +41,7 @@
|
||||||
#define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states
|
#define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states
|
||||||
|
|
||||||
#define STATE_FILES_DIRECTORY "hardnested/tables/"
|
#define STATE_FILES_DIRECTORY "hardnested/tables/"
|
||||||
#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin"
|
#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.z"
|
||||||
|
|
||||||
#define DEBUG_KEY_ELIMINATION
|
#define DEBUG_KEY_ELIMINATION
|
||||||
// #define DEBUG_REDUCTION
|
// #define DEBUG_REDUCTION
|
||||||
|
@ -70,6 +71,7 @@ static float brute_force_per_second;
|
||||||
|
|
||||||
|
|
||||||
static void get_SIMD_instruction_set(char* instruction_set) {
|
static void get_SIMD_instruction_set(char* instruction_set) {
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8))
|
#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8))
|
||||||
#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2)
|
#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2)
|
||||||
if (__builtin_cpu_supports("avx512f")) strcpy(instruction_set, "AVX512F");
|
if (__builtin_cpu_supports("avx512f")) strcpy(instruction_set, "AVX512F");
|
||||||
|
@ -82,7 +84,8 @@ static void get_SIMD_instruction_set(char* instruction_set) {
|
||||||
else if (__builtin_cpu_supports("mmx")) strcpy(instruction_set, "MMX");
|
else if (__builtin_cpu_supports("mmx")) strcpy(instruction_set, "MMX");
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
strcpy(instruction_set, "unsupported");
|
#endif
|
||||||
|
strcpy(instruction_set, "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,12 +243,48 @@ static int compare_count_bitflip_bitarrays(const void *b1, const void *b2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size)
|
||||||
|
{
|
||||||
|
return malloc(items*size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void inflate_free(voidpf opaque, voidpf address)
|
||||||
|
{
|
||||||
|
free(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OUTPUT_BUFFER_LEN 80
|
||||||
|
#define INPUT_BUFFER_LEN 80
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Initialize decompression of the respective (HF or LF) FPGA stream
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static void init_inflate(z_streamp compressed_stream, uint8_t *input_buffer, uint32_t insize, uint8_t *output_buffer, uint32_t outsize)
|
||||||
|
{
|
||||||
|
|
||||||
|
// initialize z_stream structure for inflate:
|
||||||
|
compressed_stream->next_in = input_buffer;
|
||||||
|
compressed_stream->avail_in = insize;
|
||||||
|
compressed_stream->next_out = output_buffer;
|
||||||
|
compressed_stream->avail_out = outsize;
|
||||||
|
compressed_stream->zalloc = &inflate_malloc;
|
||||||
|
compressed_stream->zfree = &inflate_free;
|
||||||
|
|
||||||
|
inflateInit2(compressed_stream, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void init_bitflip_bitarrays(void)
|
static void init_bitflip_bitarrays(void)
|
||||||
{
|
{
|
||||||
#if defined (DEBUG_REDUCTION)
|
#if defined (DEBUG_REDUCTION)
|
||||||
uint8_t line = 0;
|
uint8_t line = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
z_stream compressed_stream;
|
||||||
|
|
||||||
char state_files_path[strlen(get_my_executable_directory()) + strlen(STATE_FILES_DIRECTORY) + strlen(STATE_FILE_TEMPLATE) + 1];
|
char state_files_path[strlen(get_my_executable_directory()) + strlen(STATE_FILES_DIRECTORY) + strlen(STATE_FILE_TEMPLATE) + 1];
|
||||||
char state_file_name[strlen(STATE_FILE_TEMPLATE)+1];
|
char state_file_name[strlen(STATE_FILE_TEMPLATE)+1];
|
||||||
|
|
||||||
|
@ -262,22 +301,31 @@ static void init_bitflip_bitarrays(void)
|
||||||
if (statesfile == NULL) {
|
if (statesfile == NULL) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1<<19));
|
fseek(statesfile, 0, SEEK_END);
|
||||||
if (bitset == NULL) {
|
uint32_t filesize = (uint32_t)ftell(statesfile);
|
||||||
printf("Out of memory error in init_bitflip_statelists(). Aborting...\n");
|
rewind(statesfile);
|
||||||
|
uint8_t input_buffer[filesize];
|
||||||
|
size_t bytesread = fread(input_buffer, 1, filesize, statesfile);
|
||||||
|
if (bytesread != filesize) {
|
||||||
|
printf("File read error with %s. Aborting...\n", state_file_name);
|
||||||
fclose(statesfile);
|
fclose(statesfile);
|
||||||
exit(4);
|
inflateEnd(&compressed_stream);
|
||||||
}
|
|
||||||
size_t bytesread = fread(bitset, 1, sizeof(uint32_t) * (1<<19), statesfile);
|
|
||||||
if (bytesread != sizeof(uint32_t) * (1<<19)) {
|
|
||||||
printf("File read error with %s. Aborting...", state_file_name);
|
|
||||||
fclose(statesfile);
|
|
||||||
free_bitarray(bitset);
|
|
||||||
exit(5);
|
exit(5);
|
||||||
}
|
}
|
||||||
fclose(statesfile);
|
fclose(statesfile);
|
||||||
uint32_t count = count_states(bitset);
|
uint32_t count = 0;
|
||||||
|
init_inflate(&compressed_stream, input_buffer, filesize, (uint8_t *)&count, sizeof(count));
|
||||||
|
inflate(&compressed_stream, Z_SYNC_FLUSH);
|
||||||
if ((float)count/(1<<24) < IGNORE_BITFLIP_THRESHOLD) {
|
if ((float)count/(1<<24) < IGNORE_BITFLIP_THRESHOLD) {
|
||||||
|
uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1<<19));
|
||||||
|
if (bitset == NULL) {
|
||||||
|
printf("Out of memory error in init_bitflip_statelists(). Aborting...\n");
|
||||||
|
inflateEnd(&compressed_stream);
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
compressed_stream.next_out = (uint8_t *)bitset;
|
||||||
|
compressed_stream.avail_out = sizeof(uint32_t) * (1<<19);
|
||||||
|
inflate(&compressed_stream, Z_SYNC_FLUSH);
|
||||||
effective_bitflip[odd_even][num_effective_bitflips[odd_even]++] = bitflip;
|
effective_bitflip[odd_even][num_effective_bitflips[odd_even]++] = bitflip;
|
||||||
bitflip_bitarrays[odd_even][bitflip] = bitset;
|
bitflip_bitarrays[odd_even][bitflip] = bitset;
|
||||||
count_bitflip_bitarrays[odd_even][bitflip] = count;
|
count_bitflip_bitarrays[odd_even][bitflip] = count;
|
||||||
|
@ -289,9 +337,8 @@ static void init_bitflip_bitarrays(void)
|
||||||
line = 0;
|
line = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
|
||||||
free_bitarray(bitset);
|
|
||||||
}
|
}
|
||||||
|
inflateEnd(&compressed_stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effective_bitflip[odd_even][num_effective_bitflips[odd_even]] = 0x400; // EndOfList marker
|
effective_bitflip[odd_even][num_effective_bitflips[odd_even]] = 0x400; // EndOfList marker
|
||||||
|
@ -2549,6 +2596,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
||||||
best_first_bytes[0] = best_first_byte_smallest_bitarray;
|
best_first_bytes[0] = best_first_byte_smallest_bitarray;
|
||||||
pre_XOR_nonces();
|
pre_XOR_nonces();
|
||||||
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
|
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
|
||||||
|
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0);
|
||||||
key_found = brute_force();
|
key_found = brute_force();
|
||||||
free(candidates->states[ODD_STATE]);
|
free(candidates->states[ODD_STATE]);
|
||||||
free(candidates->states[EVEN_STATE]);
|
free(candidates->states[EVEN_STATE]);
|
||||||
|
@ -2568,6 +2616,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
||||||
// printf("Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0));
|
// printf("Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0));
|
||||||
generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx);
|
generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx);
|
||||||
// printf("Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0);
|
// printf("Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0);
|
||||||
|
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0);
|
||||||
key_found = brute_force();
|
key_found = brute_force();
|
||||||
free_statelist_cache();
|
free_statelist_cache();
|
||||||
free_candidates_memory(candidates);
|
free_candidates_memory(candidates);
|
||||||
|
@ -2608,6 +2657,12 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
||||||
|
|
||||||
if (nonce_file_read) { // use pre-acquired data from file nonces.bin
|
if (nonce_file_read) { // use pre-acquired data from file nonces.bin
|
||||||
if (read_nonce_file() != 0) {
|
if (read_nonce_file() != 0) {
|
||||||
|
free_bitflip_bitarrays();
|
||||||
|
free_nonces_memory();
|
||||||
|
free_bitarray(all_bitflips_bitarray[ODD_STATE]);
|
||||||
|
free_bitarray(all_bitflips_bitarray[EVEN_STATE]);
|
||||||
|
free_sum_bitarrays();
|
||||||
|
free_part_sum_bitarrays();
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
hardnested_stage = CHECK_1ST_BYTES | CHECK_2ND_BYTES;
|
hardnested_stage = CHECK_1ST_BYTES | CHECK_2ND_BYTES;
|
||||||
|
@ -2617,6 +2672,12 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
||||||
} else { // acquire nonces.
|
} else { // acquire nonces.
|
||||||
uint16_t is_OK = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow);
|
uint16_t is_OK = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow);
|
||||||
if (is_OK != 0) {
|
if (is_OK != 0) {
|
||||||
|
free_bitflip_bitarrays();
|
||||||
|
free_nonces_memory();
|
||||||
|
free_bitarray(all_bitflips_bitarray[ODD_STATE]);
|
||||||
|
free_bitarray(all_bitflips_bitarray[EVEN_STATE]);
|
||||||
|
free_sum_bitarrays();
|
||||||
|
free_part_sum_bitarrays();
|
||||||
return is_OK;
|
return is_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2646,10 +2707,11 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
||||||
for (statelist_t *sl = candidates; sl != NULL; sl = sl->next) {
|
for (statelist_t *sl = candidates; sl != NULL; sl = sl->next) {
|
||||||
maximum_states += (uint64_t)sl->len[ODD_STATE] * sl->len[EVEN_STATE];
|
maximum_states += (uint64_t)sl->len[ODD_STATE] * sl->len[EVEN_STATE];
|
||||||
}
|
}
|
||||||
printf("Number of remaining possible keys: %" PRIu64 " (2^%1.1f)\n", maximum_states, log(maximum_states)/log(2.0));
|
// printf("Number of remaining possible keys: %" PRIu64 " (2^%1.1f)\n", maximum_states, log(maximum_states)/log(2.0));
|
||||||
best_first_bytes[0] = best_first_byte_smallest_bitarray;
|
best_first_bytes[0] = best_first_byte_smallest_bitarray;
|
||||||
pre_XOR_nonces();
|
pre_XOR_nonces();
|
||||||
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
|
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
|
||||||
|
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0);
|
||||||
key_found = brute_force();
|
key_found = brute_force();
|
||||||
free(candidates->states[ODD_STATE]);
|
free(candidates->states[ODD_STATE]);
|
||||||
free(candidates->states[EVEN_STATE]);
|
free(candidates->states[EVEN_STATE]);
|
||||||
|
@ -2669,6 +2731,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
||||||
// printf("Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0));
|
// printf("Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0));
|
||||||
generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx);
|
generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx);
|
||||||
// printf("Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0);
|
// printf("Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0);
|
||||||
|
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0);
|
||||||
key_found = brute_force();
|
key_found = brute_force();
|
||||||
free_statelist_cache();
|
free_statelist_cache();
|
||||||
free_candidates_memory(candidates);
|
free_candidates_memory(candidates);
|
||||||
|
|
|
@ -49,7 +49,7 @@ uint8_t default_3des_keys[KEYS_3DES_COUNT][16] = {
|
||||||
{ 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF } // 11 22 33
|
{ 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF } // 11 22 33
|
||||||
};
|
};
|
||||||
|
|
||||||
#define KEYS_PWD_COUNT 10
|
#define KEYS_PWD_COUNT 6
|
||||||
uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = {
|
uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = {
|
||||||
{0xFF,0xFF,0xFF,0xFF}, // PACK 0x00,0x00 -- factory default
|
{0xFF,0xFF,0xFF,0xFF}, // PACK 0x00,0x00 -- factory default
|
||||||
|
|
||||||
|
@ -58,11 +58,6 @@ uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = {
|
||||||
{0xFF,0x90,0x6C,0xB2}, // PACK 0x12,0x9e -- italian bus (sniffed)
|
{0xFF,0x90,0x6C,0xB2}, // PACK 0x12,0x9e -- italian bus (sniffed)
|
||||||
{0x46,0x1c,0xA3,0x19}, // PACK 0xE9,0x5A -- italian bus (sniffed)
|
{0x46,0x1c,0xA3,0x19}, // PACK 0xE9,0x5A -- italian bus (sniffed)
|
||||||
{0x35,0x1C,0xD0,0x19}, // PACK 0x9A,0x5a -- italian bus (sniffed)
|
{0x35,0x1C,0xD0,0x19}, // PACK 0x9A,0x5a -- italian bus (sniffed)
|
||||||
|
|
||||||
{0x05,0x22,0xE6,0xB4}, // PACK 0x80,0x80 -- Amiiboo (sniffed) pikachu-b UID:
|
|
||||||
{0x7E,0x22,0xE6,0xB4}, // PACK 0x80,0x80 -- AMiiboo (sniffed)
|
|
||||||
{0x02,0xE1,0xEE,0x36}, // PACK 0x80,0x80 -- AMiiboo (sniffed) sonic UID: 04d257 7ae33e8027
|
|
||||||
{0x32,0x0C,0x16,0x17}, // PACK 0x80,0x80 -- AMiiboo (sniffed)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_UL_TYPES 18
|
#define MAX_UL_TYPES 18
|
||||||
|
@ -1129,9 +1124,9 @@ int CmdHF14AMfURdBl(const char *Cmd){
|
||||||
uint8_t isOK = resp.arg[0] & 0xff;
|
uint8_t isOK = resp.arg[0] & 0xff;
|
||||||
if (isOK) {
|
if (isOK) {
|
||||||
uint8_t *data = resp.d.asBytes;
|
uint8_t *data = resp.d.asBytes;
|
||||||
PrintAndLog("\nBlock# | Data | Ascii");
|
PrintAndLog("\n Block# | Data | Ascii");
|
||||||
PrintAndLog("-----------------------------");
|
PrintAndLog("---------+-------------+------");
|
||||||
PrintAndLog("%02d/0x%02X | %s| %.4s\n", blockNo, blockNo, sprint_hex(data, 4), data);
|
PrintAndLog(" %02d/0x%02X | %s| %.4s\n", blockNo, blockNo, sprint_hex(data, 4), data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PrintAndLog("Failed reading block: (%02x)", isOK);
|
PrintAndLog("Failed reading block: (%02x)", isOK);
|
||||||
|
@ -1377,8 +1372,8 @@ int CmdHF14AMfUDump(const char *Cmd){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("\nBlock# | Data |lck| Ascii");
|
PrintAndLog("\n Block# | Data |lck| Ascii");
|
||||||
PrintAndLog("---------------------------------");
|
PrintAndLog("---------+-------------+---+------");
|
||||||
for (i = 0; i < Pages; ++i) {
|
for (i = 0; i < Pages; ++i) {
|
||||||
if ( i < 3 ) {
|
if ( i < 3 ) {
|
||||||
PrintAndLog("%3d/0x%02X | %s| | ", i+startPage, i+startPage, sprint_hex(data + i * 4, 4));
|
PrintAndLog("%3d/0x%02X | %s| | ", i+startPage, i+startPage, sprint_hex(data + i * 4, 4));
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "cmdlfjablotron.h" //for jablotron menu
|
#include "cmdlfjablotron.h" //for jablotron menu
|
||||||
#include "cmdlfnoralsy.h"// for noralsy menu
|
#include "cmdlfnoralsy.h"// for noralsy menu
|
||||||
#include "cmdlfsecurakey.h"//for securakey menu
|
#include "cmdlfsecurakey.h"//for securakey menu
|
||||||
|
#include "cmdlfpac.h" // for pac menu
|
||||||
|
|
||||||
bool g_lf_threshold_set = false;
|
bool g_lf_threshold_set = false;
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
@ -349,7 +350,8 @@ bool lf_read(bool silent, uint32_t samples) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getSamples(resp.arg[0], silent);
|
// resp.arg[0] is bits read not bytes read.
|
||||||
|
getSamples(resp.arg[0]/8, silent);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1055,6 +1057,12 @@ int CmdLFfind(const char *Cmd)
|
||||||
return CheckChipType(cmdp);
|
return CheckChipType(cmdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ans=CmdPacDemod("");
|
||||||
|
if (ans>0) {
|
||||||
|
PrintAndLog("\nValid PAC/Stanley ID Found!");
|
||||||
|
return CheckChipType(cmdp);
|
||||||
|
}
|
||||||
|
|
||||||
PrintAndLog("\nNo Known Tags Found!\n");
|
PrintAndLog("\nNo Known Tags Found!\n");
|
||||||
if (testRaw=='u' || testRaw=='U') {
|
if (testRaw=='u' || testRaw=='U') {
|
||||||
//ans=CheckChipType(cmdp);
|
//ans=CheckChipType(cmdp);
|
||||||
|
@ -1081,7 +1089,7 @@ int CmdLFfind(const char *Cmd)
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
|
PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
|
||||||
PrintAndLog("\nCould also be PSK3 - [currently not supported]");
|
PrintAndLog("\nCould also be PSK3 - [currently not supported]");
|
||||||
PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod'");
|
PrintAndLog("\nCould also be NRZ - try 'data rawdemod nr'");
|
||||||
return CheckChipType(cmdp);
|
return CheckChipType(cmdp);
|
||||||
}
|
}
|
||||||
ans = CheckChipType(cmdp);
|
ans = CheckChipType(cmdp);
|
||||||
|
@ -1105,6 +1113,7 @@ static command_t CommandTable[] =
|
||||||
{"jablotron", CmdLFJablotron, 1, "{ Jablotron RFIDs... }"},
|
{"jablotron", CmdLFJablotron, 1, "{ Jablotron RFIDs... }"},
|
||||||
{"nexwatch", CmdLFNexWatch, 1, "{ NexWatch RFIDs... }"},
|
{"nexwatch", CmdLFNexWatch, 1, "{ NexWatch RFIDs... }"},
|
||||||
{"noralsy", CmdLFNoralsy, 1, "{ Noralsy RFIDs... }"},
|
{"noralsy", CmdLFNoralsy, 1, "{ Noralsy RFIDs... }"},
|
||||||
|
{"pac", CmdLFPac, 1, "{ PAC/Stanley RFIDs... }"},
|
||||||
{"paradox", CmdLFParadox, 1, "{ Paradox RFIDs... }"},
|
{"paradox", CmdLFParadox, 1, "{ Paradox RFIDs... }"},
|
||||||
{"presco", CmdLFPresco, 1, "{ Presco RFIDs... }"},
|
{"presco", CmdLFPresco, 1, "{ Presco RFIDs... }"},
|
||||||
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 CHIPs... }"},
|
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 CHIPs... }"},
|
||||||
|
|
|
@ -23,10 +23,12 @@
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
#include "lfdemod.h"
|
#include "lfdemod.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
|
#include "util_posix.h"
|
||||||
|
|
||||||
uint64_t g_em410xId=0;
|
uint64_t g_em410xId=0;
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
void ConstructEM410xEmulGraph(const char *uid,const uint8_t clock);
|
||||||
|
|
||||||
int CmdEMdemodASK(const char *Cmd)
|
int CmdEMdemodASK(const char *Cmd)
|
||||||
{
|
{
|
||||||
|
@ -216,28 +218,10 @@ int usage_lf_em410x_sim(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// emulate an EM410X tag
|
// Construct the graph for emulating an EM410X tag
|
||||||
int CmdEM410xSim(const char *Cmd)
|
void ConstructEM410xEmulGraph(const char *uid,const uint8_t clock)
|
||||||
{
|
{
|
||||||
int i, n, j, binary[4], parity[4];
|
int i, n, j, binary[4], parity[4];
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
|
||||||
uint8_t uid[5] = {0x00};
|
|
||||||
|
|
||||||
if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_sim();
|
|
||||||
/* clock is 64 in EM410x tags */
|
|
||||||
uint8_t clock = 64;
|
|
||||||
|
|
||||||
if (param_gethex(Cmd, 0, uid, 10)) {
|
|
||||||
PrintAndLog("UID must include 10 HEX symbols");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
param_getdec(Cmd,1, &clock);
|
|
||||||
|
|
||||||
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock);
|
|
||||||
PrintAndLog("Press pm3-button to about simulation");
|
|
||||||
|
|
||||||
|
|
||||||
/* clear our graph */
|
/* clear our graph */
|
||||||
ClearGraph(0);
|
ClearGraph(0);
|
||||||
|
|
||||||
|
@ -247,10 +231,9 @@ int CmdEM410xSim(const char *Cmd)
|
||||||
|
|
||||||
/* for each hex char */
|
/* for each hex char */
|
||||||
parity[0] = parity[1] = parity[2] = parity[3] = 0;
|
parity[0] = parity[1] = parity[2] = parity[3] = 0;
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++){
|
||||||
{
|
|
||||||
/* read each hex char */
|
/* read each hex char */
|
||||||
sscanf(&Cmd[i], "%1x", &n);
|
sscanf(&uid[i], "%1x", &n);
|
||||||
for (j = 3; j >= 0; j--, n/= 2)
|
for (j = 3; j >= 0; j--, n/= 2)
|
||||||
binary[j] = n % 2;
|
binary[j] = n % 2;
|
||||||
|
|
||||||
|
@ -278,11 +261,165 @@ int CmdEM410xSim(const char *Cmd)
|
||||||
|
|
||||||
/* stop bit */
|
/* stop bit */
|
||||||
AppendGraph(1, clock, 0);
|
AppendGraph(1, clock, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// emulate an EM410X tag
|
||||||
|
int CmdEM410xSim(const char *Cmd)
|
||||||
|
{
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
uint8_t uid[5] = {0x00};
|
||||||
|
|
||||||
|
if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_sim();
|
||||||
|
/* clock is 64 in EM410x tags */
|
||||||
|
uint8_t clock = 64;
|
||||||
|
|
||||||
|
if (param_gethex(Cmd, 0, uid, 10)) {
|
||||||
|
PrintAndLog("UID must include 10 HEX symbols");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
param_getdec(Cmd,1, &clock);
|
||||||
|
|
||||||
|
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock);
|
||||||
|
PrintAndLog("Press pm3-button to abort simulation");
|
||||||
|
|
||||||
|
ConstructEM410xEmulGraph(Cmd, clock);
|
||||||
|
|
||||||
CmdLFSim("0"); //240 start_gap.
|
CmdLFSim("0"); //240 start_gap.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int usage_lf_em410x_brute(void) {
|
||||||
|
PrintAndLog("Bruteforcing by emulating EM410x tag");
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("Usage: lf em 410xbrute [h] ids.txt [d 2000] [c clock]");
|
||||||
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" h - this help");
|
||||||
|
PrintAndLog(" ids.txt - file with UIDs in HEX format, one per line");
|
||||||
|
PrintAndLog(" d (2000) - pause delay in milliseconds between UIDs simulation, default 1000 ms (optional)");
|
||||||
|
PrintAndLog(" c (32) - clock (32|64), default 64 (optional)");
|
||||||
|
PrintAndLog("samples:");
|
||||||
|
PrintAndLog(" lf em 410xbrute ids.txt");
|
||||||
|
PrintAndLog(" lf em 410xbrute ids.txt c 32");
|
||||||
|
PrintAndLog(" lf em 410xbrute ids.txt d 3000");
|
||||||
|
PrintAndLog(" lf em 410xbrute ids.txt d 3000 c 32");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdEM410xBrute(const char *Cmd)
|
||||||
|
{
|
||||||
|
char filename[FILE_PATH_SIZE]={0};
|
||||||
|
FILE *f = NULL;
|
||||||
|
char buf[11];
|
||||||
|
uint32_t uidcnt = 0;
|
||||||
|
uint8_t stUidBlock = 20;
|
||||||
|
uint8_t *uidBlock = NULL, *p = NULL;
|
||||||
|
int ch;
|
||||||
|
uint8_t uid[5] = {0x00};
|
||||||
|
/* clock is 64 in EM410x tags */
|
||||||
|
uint8_t clock = 64;
|
||||||
|
/* default pause time: 1 second */
|
||||||
|
uint32_t delay = 1000;
|
||||||
|
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
|
if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_brute();
|
||||||
|
|
||||||
|
|
||||||
|
cmdp = param_getchar(Cmd, 1);
|
||||||
|
|
||||||
|
if (cmdp == 'd' || cmdp == 'D') {
|
||||||
|
delay = param_get32ex(Cmd, 2, 1000, 10);
|
||||||
|
param_getdec(Cmd, 4, &clock);
|
||||||
|
} else if (cmdp == 'c' || cmdp == 'C') {
|
||||||
|
param_getdec(Cmd, 2, &clock);
|
||||||
|
delay = param_get32ex(Cmd, 4, 1000, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
param_getstr(Cmd, 0, filename);
|
||||||
|
|
||||||
|
uidBlock = calloc(stUidBlock, 5);
|
||||||
|
if (uidBlock == NULL) return 1;
|
||||||
|
|
||||||
|
if (strlen(filename) > 0) {
|
||||||
|
if ((f = fopen(filename, "r")) == NULL) {
|
||||||
|
PrintAndLog("Error: Could not open UIDs file [%s]",filename);
|
||||||
|
free(uidBlock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Error: Please specify a filename");
|
||||||
|
free(uidBlock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( fgets(buf, sizeof(buf), f) ) {
|
||||||
|
if (strlen(buf) < 10 || buf[9] == '\n') continue;
|
||||||
|
while (fgetc(f) != '\n' && !feof(f)); //goto next line
|
||||||
|
|
||||||
|
//The line start with # is comment, skip
|
||||||
|
if( buf[0]=='#' ) continue;
|
||||||
|
|
||||||
|
if (param_gethex(buf, 0, uid, 10)) {
|
||||||
|
PrintAndLog("UIDs must include 10 HEX symbols");
|
||||||
|
free(uidBlock);
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[10] = 0;
|
||||||
|
|
||||||
|
if ( stUidBlock - uidcnt < 2) {
|
||||||
|
p = realloc(uidBlock, 5*(stUidBlock+=10));
|
||||||
|
if (!p) {
|
||||||
|
PrintAndLog("Cannot allocate memory for UIDs");
|
||||||
|
free(uidBlock);
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
uidBlock = p;
|
||||||
|
}
|
||||||
|
memset(uidBlock + 5 * uidcnt, 0, 5);
|
||||||
|
num_to_bytes(strtoll(buf, NULL, 16), 5, uidBlock + 5*uidcnt);
|
||||||
|
uidcnt++;
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (uidcnt == 0) {
|
||||||
|
PrintAndLog("No UIDs found in file");
|
||||||
|
free(uidBlock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
PrintAndLog("Loaded %d UIDs from %s, pause delay: %d ms", uidcnt, filename, delay);
|
||||||
|
|
||||||
|
// loop
|
||||||
|
for(uint32_t c = 0; c < uidcnt; ++c ) {
|
||||||
|
char testuid[11];
|
||||||
|
testuid[10] = 0;
|
||||||
|
|
||||||
|
if (ukbhit()) {
|
||||||
|
ch = getchar();
|
||||||
|
(void)ch;
|
||||||
|
printf("\nAborted via keyboard!\n");
|
||||||
|
free(uidBlock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(testuid, "%010" PRIX64, bytes_to_num(uidBlock + 5*c, 5));
|
||||||
|
PrintAndLog("Bruteforce %d / %d: simulating UID %s, clock %d", c + 1, uidcnt, testuid, clock);
|
||||||
|
|
||||||
|
ConstructEM410xEmulGraph(testuid, clock);
|
||||||
|
|
||||||
|
CmdLFSim("0"); //240 start_gap.
|
||||||
|
|
||||||
|
msleep(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(uidBlock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function is equivalent of lf read + data samples + em410xread
|
/* Function is equivalent of lf read + data samples + em410xread
|
||||||
* looped until an EM410x tag is detected
|
* looped until an EM410x tag is detected
|
||||||
*
|
*
|
||||||
|
@ -1202,6 +1339,7 @@ static command_t CommandTable[] =
|
||||||
{"410xread", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
|
{"410xread", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
|
||||||
{"410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
|
{"410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
|
||||||
{"410xsim", CmdEM410xSim, 0, "<UID> [clock rate] -- Simulate EM410x tag"},
|
{"410xsim", CmdEM410xSim, 0, "<UID> [clock rate] -- Simulate EM410x tag"},
|
||||||
|
{"410xbrute", CmdEM410xBrute, 0, "ids.txt [d (delay in ms)] [c (clock rate)] -- Reader bruteforce attack by simulating EM410x tags"},
|
||||||
{"410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
{"410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
||||||
{"410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
{"410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
||||||
{"410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
|
{"410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
|
||||||
|
|
|
@ -21,6 +21,7 @@ extern int CmdAskEM410xDemod(const char *Cmd);
|
||||||
extern int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo );
|
extern int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo );
|
||||||
extern int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose);
|
extern int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose);
|
||||||
extern int CmdEM410xSim(const char *Cmd);
|
extern int CmdEM410xSim(const char *Cmd);
|
||||||
|
extern int CmdEM410xBrute(const char *Cmd);
|
||||||
extern int CmdEM410xWatch(const char *Cmd);
|
extern int CmdEM410xWatch(const char *Cmd);
|
||||||
extern int CmdEM410xWatchnSpoof(const char *Cmd);
|
extern int CmdEM410xWatchnSpoof(const char *Cmd);
|
||||||
extern int CmdEM410xWrite(const char *Cmd);
|
extern int CmdEM410xWrite(const char *Cmd);
|
||||||
|
|
|
@ -349,7 +349,9 @@ int CmdLFHitagWP(const char *Cmd) {
|
||||||
c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
|
c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
|
||||||
num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->auth.data);
|
num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->auth.data);
|
||||||
} break;
|
} break;
|
||||||
case 04: { //WHTSF_KEY
|
case 04:
|
||||||
|
case 24:
|
||||||
|
{ //WHTSF_KEY
|
||||||
num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
|
num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
|
||||||
c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
|
c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
|
||||||
num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->crypto.data);
|
num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->crypto.data);
|
||||||
|
@ -363,6 +365,7 @@ int CmdLFHitagWP(const char *Cmd) {
|
||||||
PrintAndLog(" 04 <key> (set to 0 if no authentication is needed) <page> <byte0...byte3> write page on a Hitag S tag");
|
PrintAndLog(" 04 <key> (set to 0 if no authentication is needed) <page> <byte0...byte3> write page on a Hitag S tag");
|
||||||
PrintAndLog(" Hitag1 (1*)");
|
PrintAndLog(" Hitag1 (1*)");
|
||||||
PrintAndLog(" Hitag2 (2*)");
|
PrintAndLog(" Hitag2 (2*)");
|
||||||
|
PrintAndLog(" 24 <key> (set to 0 if no authentication is needed) <page> <byte0...byte3> write page on a Hitag S tag");
|
||||||
return 1;
|
return 1;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,8 +96,12 @@ int CmdIndalaDemod(const char *Cmd) {
|
||||||
uint8_t rawbits[4096];
|
uint8_t rawbits[4096];
|
||||||
int rawbit = 0;
|
int rawbit = 0;
|
||||||
int worst = 0, worstPos = 0;
|
int worst = 0, worstPos = 0;
|
||||||
// PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
|
|
||||||
|
|
||||||
|
//clear clock grid and demod plot
|
||||||
|
setClockGrid(0, 0);
|
||||||
|
DemodBufferLen = 0;
|
||||||
|
|
||||||
|
// PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
|
||||||
// loop through raw signal - since we know it is psk1 rf/32 fc/2 skip every other value (+=2)
|
// loop through raw signal - since we know it is psk1 rf/32 fc/2 skip every other value (+=2)
|
||||||
for (i = 0; i < GraphTraceLen-1; i += 2) {
|
for (i = 0; i < GraphTraceLen-1; i += 2) {
|
||||||
count += 1;
|
count += 1;
|
||||||
|
|
|
@ -133,20 +133,21 @@ int CmdIOClone(const char *Cmd)
|
||||||
{
|
{
|
||||||
unsigned int hi = 0, lo = 0;
|
unsigned int hi = 0, lo = 0;
|
||||||
int n = 0, i = 0;
|
int n = 0, i = 0;
|
||||||
|
char ch;
|
||||||
UsbCommand c;
|
UsbCommand c;
|
||||||
|
|
||||||
|
|
||||||
//if (1 == sscanf(str, "0x%"SCNx32, &hi)) {
|
|
||||||
// value now contains the value in the string--decimal 255, in this case.
|
|
||||||
//}
|
|
||||||
|
|
||||||
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
|
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
|
||||||
hi = (hi << 4) | (lo >> 28);
|
hi = (hi << 4) | (lo >> 28);
|
||||||
lo = (lo << 4) | (n & 0xf);
|
lo = (lo << 4) | (n & 0xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("Cloning tag with ID %08x %08x", hi, lo);
|
if (sscanf(&Cmd[--i], "%c", &ch) == 1) {
|
||||||
PrintAndLog("Press pm3-button to abort simulation");
|
PrintAndLog("Usage: lf io clone <tag-ID>");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("Cloning ioProx tag with ID %08x %08x", hi, lo);
|
||||||
|
|
||||||
c.cmd = CMD_IO_CLONE_TAG;
|
c.cmd = CMD_IO_CLONE_TAG;
|
||||||
c.arg[0] = hi;
|
c.arg[0] = hi;
|
||||||
c.arg[1] = lo;
|
c.arg[1] = lo;
|
||||||
|
|
100
client/cmdlfpac.c
Normal file
100
client/cmdlfpac.c
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency Stanley/PAC tag commands
|
||||||
|
// NRZ, RF/32, 128 bits long (unknown cs)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#include "cmdlfpac.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "proxmark3.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "graph.h"
|
||||||
|
#include "cmdparser.h"
|
||||||
|
#include "cmddata.h"
|
||||||
|
#include "cmdmain.h"
|
||||||
|
#include "cmdlf.h"
|
||||||
|
#include "lfdemod.h" // preamble test
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
// by marshmellow
|
||||||
|
// find PAC preamble in already demoded data
|
||||||
|
int PacFind(uint8_t *dest, size_t *size) {
|
||||||
|
if (*size < 128) return -1; //make sure buffer has data
|
||||||
|
size_t startIdx = 0;
|
||||||
|
uint8_t preamble[] = {1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,1,0};
|
||||||
|
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
|
||||||
|
return -2; //preamble not found
|
||||||
|
if (*size != 128) return -3; //wrong demoded size
|
||||||
|
//return start position
|
||||||
|
return (int)startIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
//see NRZDemod for what args are accepted
|
||||||
|
int CmdPacDemod(const char *Cmd) {
|
||||||
|
|
||||||
|
//NRZ
|
||||||
|
if (!NRZrawDemod(Cmd, false)) {
|
||||||
|
if (g_debugMode) PrintAndLog("DEBUG: Error - PAC: NRZ Demod failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
size_t size = DemodBufferLen;
|
||||||
|
int ans = PacFind(DemodBuffer, &size);
|
||||||
|
if (ans < 0) {
|
||||||
|
if (g_debugMode) {
|
||||||
|
if (ans == -1)
|
||||||
|
PrintAndLog("DEBUG: Error - PAC: too few bits found");
|
||||||
|
else if (ans == -2)
|
||||||
|
PrintAndLog("DEBUG: Error - PAC: preamble not found");
|
||||||
|
else if (ans == -3)
|
||||||
|
PrintAndLog("DEBUG: Error - PAC: Size not correct: %d", size);
|
||||||
|
else
|
||||||
|
PrintAndLog("DEBUG: Error - PAC: ans: %d", ans);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
setDemodBuf(DemodBuffer, 128, ans);
|
||||||
|
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
|
||||||
|
|
||||||
|
//got a good demod
|
||||||
|
uint32_t raw1 = bytebits_to_byte(DemodBuffer , 32);
|
||||||
|
uint32_t raw2 = bytebits_to_byte(DemodBuffer+32, 32);
|
||||||
|
uint32_t raw3 = bytebits_to_byte(DemodBuffer+64, 32);
|
||||||
|
uint32_t raw4 = bytebits_to_byte(DemodBuffer+96, 32);
|
||||||
|
|
||||||
|
// preamble then appears to have marker bits of "10" CS?
|
||||||
|
// 11111111001000000 10 01001100 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 10001100 10 100000001
|
||||||
|
// unknown checksum 9 bits at the end
|
||||||
|
|
||||||
|
PrintAndLog("PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1 ,raw2, raw3, raw4);
|
||||||
|
PrintAndLog("\nHow the Raw ID is translated by the reader is unknown");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdPacRead(const char *Cmd) {
|
||||||
|
lf_read(true, 4096*2 + 20);
|
||||||
|
return CmdPacDemod(Cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_t CommandTable[] = {
|
||||||
|
{"help", CmdHelp, 1, "This help"},
|
||||||
|
{"demod", CmdPacDemod,1, "Attempt to read and extract tag data from the GraphBuffer"},
|
||||||
|
{"read", CmdPacRead, 0, "Attempt to read and extract tag data from the antenna"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
int CmdLFPac(const char *Cmd) {
|
||||||
|
clearCommandBuffer();
|
||||||
|
CmdsParse(CommandTable, Cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdHelp(const char *Cmd) {
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return 0;
|
||||||
|
}
|
17
client/cmdlfpac.h
Normal file
17
client/cmdlfpac.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency Securakey tag commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#ifndef CMDLFPAC_H__
|
||||||
|
#define CMDLFPAC_H__
|
||||||
|
|
||||||
|
extern int CmdLFPac(const char *Cmd);
|
||||||
|
extern int CmdPacRead(const char *Cmd);
|
||||||
|
extern int CmdPacDemod(const char *Cmd);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -44,7 +44,7 @@ int CmdSecurakeyDemod(const char *Cmd) {
|
||||||
//ASK / Manchester
|
//ASK / Manchester
|
||||||
bool st = false;
|
bool st = false;
|
||||||
if (!ASKDemod_ext("40 0 0", false, false, 1, &st)) {
|
if (!ASKDemod_ext("40 0 0", false, false, 1, &st)) {
|
||||||
if (g_debugMode) PrintAndLog("DEBUG: Error - Noralsy: ASK/Manchester Demod failed");
|
if (g_debugMode) PrintAndLog("DEBUG: Error - Securakey: ASK/Manchester Demod failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (st) return 0;
|
if (st) return 0;
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# define unlink(x)
|
# define unlink(x)
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static serial_port sp;
|
static serial_port sp;
|
||||||
|
@ -52,8 +54,7 @@ void ReceiveCommand(UsbCommand* rxcmd) {
|
||||||
byte_t* prx = prxcmd;
|
byte_t* prx = prxcmd;
|
||||||
size_t rxlen;
|
size_t rxlen;
|
||||||
while (true) {
|
while (true) {
|
||||||
rxlen = sizeof(UsbCommand) - (prx-prxcmd);
|
if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-prxcmd), &rxlen)) {
|
||||||
if (uart_receive(sp,prx,&rxlen)) {
|
|
||||||
prx += rxlen;
|
prx += rxlen;
|
||||||
if ((prx-prxcmd) >= sizeof(UsbCommand)) {
|
if ((prx-prxcmd) >= sizeof(UsbCommand)) {
|
||||||
return;
|
return;
|
||||||
|
@ -129,7 +130,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
fprintf(stderr,"Waiting for Proxmark to appear on %s",serial_port_name);
|
fprintf(stderr,"Waiting for Proxmark to appear on %s",serial_port_name);
|
||||||
do {
|
do {
|
||||||
sleep(1);
|
msleep(1000);
|
||||||
fprintf(stderr, ".");
|
fprintf(stderr, ".");
|
||||||
} while (!OpenProxmark(0));
|
} while (!OpenProxmark(0));
|
||||||
fprintf(stderr," Found.\n");
|
fprintf(stderr," Found.\n");
|
||||||
|
|
|
@ -38,7 +38,8 @@
|
||||||
#define COMPRESS_MAX_CHAIN 8192
|
#define COMPRESS_MAX_CHAIN 8192
|
||||||
|
|
||||||
#define FPGA_INTERLEAVE_SIZE 288 // (the FPGA's internal config frame size is 288 bits. Interleaving with 288 bytes should give best compression)
|
#define FPGA_INTERLEAVE_SIZE 288 // (the FPGA's internal config frame size is 288 bits. Interleaving with 288 bytes should give best compression)
|
||||||
#define FPGA_CONFIG_SIZE 42336 // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE
|
#define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE
|
||||||
|
#define HARDNESTED_TABLE_SIZE (sizeof(uint32_t) * ((1L<<19)+1))
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
|
@ -46,6 +47,8 @@ static void usage(void)
|
||||||
fprintf(stderr, " Combine n FPGA bitstream files and compress them into one.\n\n");
|
fprintf(stderr, " Combine n FPGA bitstream files and compress them into one.\n\n");
|
||||||
fprintf(stderr, " fpga_compress -d <infile> <outfile>");
|
fprintf(stderr, " fpga_compress -d <infile> <outfile>");
|
||||||
fprintf(stderr, " Decompress <infile>. Write result to <outfile>");
|
fprintf(stderr, " Decompress <infile>. Write result to <outfile>");
|
||||||
|
fprintf(stderr, " fpga_compress -t <infile> <outfile>");
|
||||||
|
fprintf(stderr, " Compress hardnested table <infile>. Write result to <outfile>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,7 +76,7 @@ static bool all_feof(FILE *infile[], uint8_t num_infiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile)
|
int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardnested_mode)
|
||||||
{
|
{
|
||||||
uint8_t *fpga_config;
|
uint8_t *fpga_config;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -81,14 +84,21 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile)
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
z_stream compressed_fpga_stream;
|
z_stream compressed_fpga_stream;
|
||||||
|
|
||||||
|
if (hardnested_mode) {
|
||||||
|
fpga_config = malloc(num_infiles * HARDNESTED_TABLE_SIZE);
|
||||||
|
} else {
|
||||||
fpga_config = malloc(num_infiles * FPGA_CONFIG_SIZE);
|
fpga_config = malloc(num_infiles * FPGA_CONFIG_SIZE);
|
||||||
|
}
|
||||||
// read the input files. Interleave them into fpga_config[]
|
// read the input files. Interleave them into fpga_config[]
|
||||||
i = 0;
|
i = 0;
|
||||||
do {
|
do {
|
||||||
|
|
||||||
if (i >= num_infiles * FPGA_CONFIG_SIZE) {
|
if (i >= num_infiles * (hardnested_mode?HARDNESTED_TABLE_SIZE:FPGA_CONFIG_SIZE)) {
|
||||||
fprintf(stderr, "Input files too big (total > %u bytes). These are probably not PM3 FPGA config files.\n", num_infiles*FPGA_CONFIG_SIZE);
|
if (hardnested_mode) {
|
||||||
|
fprintf(stderr, "Input file too big (> %lu bytes). This is probably not a hardnested bitflip state table.\n", HARDNESTED_TABLE_SIZE);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Input files too big (total > %lu bytes). These are probably not PM3 FPGA config files.\n", num_infiles*FPGA_CONFIG_SIZE);
|
||||||
|
}
|
||||||
for(uint16_t j = 0; j < num_infiles; j++) {
|
for(uint16_t j = 0; j < num_infiles; j++) {
|
||||||
fclose(infile[j]);
|
fclose(infile[j]);
|
||||||
}
|
}
|
||||||
|
@ -253,6 +263,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(argv[1], "-d")) { // Decompress
|
if (!strcmp(argv[1], "-d")) { // Decompress
|
||||||
|
|
||||||
infiles = calloc(1, sizeof(FILE*));
|
infiles = calloc(1, sizeof(FILE*));
|
||||||
if (argc != 4) {
|
if (argc != 4) {
|
||||||
usage();
|
usage();
|
||||||
|
@ -272,11 +283,23 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
} else { // Compress
|
} else { // Compress
|
||||||
|
|
||||||
infiles = calloc(argc-2, sizeof(FILE*));
|
bool hardnested_mode = false;
|
||||||
for (uint16_t i = 0; i < argc-2; i++) {
|
int num_input_files = 0;
|
||||||
infiles[i] = fopen(argv[i+1], "rb");
|
if (!strcmp(argv[1], "-t")) { // hardnested table
|
||||||
|
if (argc != 4) {
|
||||||
|
usage();
|
||||||
|
return(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
hardnested_mode = true;
|
||||||
|
num_input_files = 1;
|
||||||
|
} else {
|
||||||
|
num_input_files = argc-2;
|
||||||
|
}
|
||||||
|
infiles = calloc(num_input_files, sizeof(FILE*));
|
||||||
|
for (uint16_t i = 0; i < num_input_files; i++) {
|
||||||
|
infiles[i] = fopen(argv[i+hardnested_mode?2:1], "rb");
|
||||||
if (infiles[i] == NULL) {
|
if (infiles[i] == NULL) {
|
||||||
fprintf(stderr, "Error. Cannot open input file %s", argv[i+1]);
|
fprintf(stderr, "Error. Cannot open input file %s", argv[i+hardnested_mode?2:1]);
|
||||||
return(EXIT_FAILURE);
|
return(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,6 +308,6 @@ int main(int argc, char **argv)
|
||||||
fprintf(stderr, "Error. Cannot open output file %s", argv[argc-1]);
|
fprintf(stderr, "Error. Cannot open output file %s", argv[argc-1]);
|
||||||
return(EXIT_FAILURE);
|
return(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
return zlib_compress(infiles, argc-2, outfile);
|
return zlib_compress(infiles, num_input_files, outfile, hardnested_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,11 +176,12 @@ static inline uint32_t count_states(uint32_t *bitset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void write_bitflips_file(odd_even_t odd_even, uint16_t bitflip, int sum_a0, uint32_t *bitset)
|
static void write_bitflips_file(odd_even_t odd_even, uint16_t bitflip, int sum_a0, uint32_t *bitset, uint32_t count)
|
||||||
{
|
{
|
||||||
char filename[80];
|
char filename[80];
|
||||||
sprintf(filename, "bitflip_%d_%03" PRIx16 "_sum%d_states.bin", odd_even, bitflip, sum_a0);
|
sprintf(filename, "bitflip_%d_%03" PRIx16 "_sum%d_states.bin", odd_even, bitflip, sum_a0);
|
||||||
FILE *outfile = fopen(filename, "wb");
|
FILE *outfile = fopen(filename, "wb");
|
||||||
|
fwrite(&count, 1, sizeof(count), outfile);
|
||||||
fwrite(bitset, 1, sizeof(uint32_t)*(1<<19), outfile);
|
fwrite(bitset, 1, sizeof(uint32_t)*(1<<19), outfile);
|
||||||
fclose(outfile);
|
fclose(outfile);
|
||||||
}
|
}
|
||||||
|
@ -369,7 +370,7 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
|
||||||
bitflip, (1<<24) - count[odd_even],
|
bitflip, (1<<24) - count[odd_even],
|
||||||
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
|
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
|
||||||
#ifndef TEST_RUN
|
#ifndef TEST_RUN
|
||||||
write_bitflips_file(odd_even, bitflip, sum_a0, test_bitarray[odd_even]);
|
write_bitflips_file(odd_even, bitflip, sum_a0, test_bitarray[odd_even], count[odd_even]);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip);
|
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip);
|
||||||
|
@ -396,7 +397,7 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
|
||||||
bitflip | BITFLIP_2ND_BYTE, (1<<24) - count[odd_even],
|
bitflip | BITFLIP_2ND_BYTE, (1<<24) - count[odd_even],
|
||||||
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
|
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
|
||||||
#ifndef TEST_RUN
|
#ifndef TEST_RUN
|
||||||
write_bitflips_file(odd_even, bitflip | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd);
|
write_bitflips_file(odd_even, bitflip | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip | BITFLIP_2ND_BYTE);
|
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip | BITFLIP_2ND_BYTE);
|
||||||
|
@ -481,7 +482,7 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
|
||||||
bitflip|0x100, (1<<24) - count[odd_even],
|
bitflip|0x100, (1<<24) - count[odd_even],
|
||||||
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
|
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
|
||||||
#ifndef TEST_RUN
|
#ifndef TEST_RUN
|
||||||
write_bitflips_file(odd_even, bitflip|0x100, sum_a0, test_not_bitarray[odd_even]);
|
write_bitflips_file(odd_even, bitflip|0x100, sum_a0, test_not_bitarray[odd_even], count[odd_even]);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip|0x100);
|
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip|0x100);
|
||||||
|
@ -508,7 +509,7 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
|
||||||
bitflip | 0x100| BITFLIP_2ND_BYTE, (1<<24) - count[odd_even],
|
bitflip | 0x100| BITFLIP_2ND_BYTE, (1<<24) - count[odd_even],
|
||||||
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
|
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
|
||||||
#ifndef TEST_RUN
|
#ifndef TEST_RUN
|
||||||
write_bitflips_file(odd_even, bitflip | 0x100 | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd);
|
write_bitflips_file(odd_even, bitflip | 0x100 | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip | 0x100 | BITFLIP_2ND_BYTE);
|
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip | 0x100 | BITFLIP_2ND_BYTE);
|
||||||
|
|
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_001_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_001_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_003_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_003_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_005_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_005_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_007_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_007_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_009_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_009_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_00b_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_00b_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_00d_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_00d_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_00f_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_00f_states.bin.z
Normal file
Binary file not shown.
Binary file not shown.
BIN
client/hardnested/tables/bitflip_0_010_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_010_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_014_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_014_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_01c_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_01c_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_021_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_021_states.bin.z
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
client/hardnested/tables/bitflip_0_023_states.bin.z
Normal file
BIN
client/hardnested/tables/bitflip_0_023_states.bin.z
Normal file
Binary file not shown.
Binary file not shown.
49
client/hardnested/tables/bitflip_0_025_states.bin.z
Normal file
49
client/hardnested/tables/bitflip_0_025_states.bin.z
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
xΪν<EFBFBD>λ<EFBFBD>λ°<EFBFBD>€§€¦¥-n›δο–1πξΩΐWλM9”Γ/ΐ<><CE90>Δ‘i<E28098>βC$EώΧ<CF8E>όχΧσ±οΗί¶=<1F>ήΏΎ<CE8F>ο~Ώ·<CE8F>{ΉλΗ<CEBB><CE97>ίύύ<<1F>ΎΫ¶pόΏχίοσψΏόϊzύ<7A>ίοΎΎόϋΝƒ<1F>ί¶ώΏoΏώ<CE8F>ώΰώ!ώΫv|·m%ψ―ίΟΗΏ~<0E>σx<1F>γίπήsα»y9γό67<36>ΠϊλΠ<CEBB>Έ―ϋϋGC<43>BψΟGί}οθ<1F>?Ύχο<CF87>9ψKΧ<4B>Όω<CE8C>ΗϋΧ<CF8B>οϊ”πί¶2όΉόίΏ†<CE8F>¶<EFBFBD>―ϋίΑ<CEAF>π?όώΨ<CF8E>ιρ?©λ!όΤσ?ερϋ^/…<1F>>Κγ΅Z<7F>=¥ωΟ}–<>ϋΏ<CF8B>ώωΣς,Ζ??:λ<>,?sΧcϊΖί§ι<C2A7>Ώ<EFBFBD><CE8F>ϊΏιϊ<CEB9>7<EFBFBD>ϋ>‡>θδΏ¦ό•Ώi~Ι??ϋ?τ?ϊϊCό<7F>Θ<EFBFBD>:|<7C>·}|<7C>ώΐΏ|β<><CEB2><EFBFBD>{όΕ<CF8C>ύ¶µοsώ<73>^ω[^<5E>ωρ9ω;<1A><>+<2B>ο<13>KΣ_*ϊα‡τ―<CF84><E28095>Χλ¶΄ώΦ“<CEA6>φϋ§<CF8B>Η<EFBFBD>Σ¶™;<3B>ΪόΧ<CF8C><CEA7>ψώωΪω»~ό»βΔ?‰b<7F>―—<E28095><E28094>j<6A>Ω<EFBFBD>Zφ<5A>mψ<6D>ω'<27><>ό?ψ<>ό?«ςΟΊ<CE9F><17>ώ?όvύRϋoVώΏVόώΗώ'ώ<><CF8E>όΑ<CF8C>ψω_δ<5F>BΫώ?νσ?Ϊη<CEAA>¬ϋ<C2AC>r<EFBFBD>ΣοσΟ?iΫ<69><CEAB><EFBFBD>γόη<>8<EFBFBD>Ηώ‡όw;π±<CF80>±<EFBFBD>‰<EFBFBD>c<EFBFBD><13>Gώ—ΰ;9§<03>ϊόoόΠίήωμ?ψϊΫ£<CEAB>Ώϋύύ„ώΓΏ<CE93>συγ{ηΏϊϋ Η<>ύ”Ηο{yΌ~<ώο§<>‡<>ο·?G<>ώομθ――σχαψΏ<CF88>γσΧ—Ώώ<CE8F>~ζΒ<CEB6>Η»λΗη――;Πί:ώο]<5D>γώηΪ{ξ~u<><EFBFBD>ώοτ<CEBF>ηπ“ϊ<E2809C>{η«wΎ[?β<CEB2>!<21>Jώ<4A>Τ~ύοη]ώ<>±υΧk<CEA7> <20>Π<EFBFBD>ϊτ<1F>?KιΏ†όOαί¶ώζΘ<CEB6>υΦ?φςΟςώΗώσμΟ1{V<56>σχΣoΞ£Ώ~~Όέ<7F>ξχ{ζώO<CF8E><4F>Χ³<CEA7>mι<6D>υψ<CF85>^ςO<CF82><4F>υχ<CF85>¶εϊ5<7F>ί¨ό<C2A8>™<EFBFBD>ί®¤ώτ?ϊ<1F>?ώό<7F>ψ<EFBFBD>ρ€?ψƒΏnό§%<25>h<EFBFBD>ό_/ώcKώCΫτ<CEAB>·<EFBFBD><C2B7>χ™ώύσχ»;ώ<>η<EFBFBD>Ηώ‡<CF8E>α;ό<><CF8C><EFBFBD>ύO‹<4F>1φί~κψάόϋγΏΫΗηθΏ|ς<><CF82><EFBFBD>k~Φ^<5E>Δ<EFBFBD>[υoΪ<6F>›?<3F>}πλγsφ'ςF<7F>0©ώm—Ώνγ¥ύ<C2A5>lϋ<6C>΄ιί²ώ―νωΞυ§m<C2A7>b<EFBFBD>Ω¶<CEA9>π<EFBFBD><13>Η<EFBFBD>ώΰOώοHόgά<67>Ώjώ<6A>υό_β<CEB2><7F>ηό+η<>Ω<EFBFBD>qώ<71>σ<EFBFBD>Θ?μ[η<>Ι<EFBFBD>!<21>ϋ<>ό?ψ<>ό?ς<>π<EFBFBD>α<EFBFBD>Γ<EFBFBD>‡ώ<E280A1>\ύ<0F>Γ<EFBFBD>πΏ5ώ<35>ϊzω£|ό<>η{qΚρέ¶ωσσο~ΗυΪψγϊ‹οBό<42>7ψΟGΫΒρ<07>VψΟΗ\ψρψmα‡ςί:ώΫvξrτ'y½Β~%ώοg¬ΏόΪϊoy~<7E>yKψ΄ΑηΫΞύ_μ:|θ7ϊΟ…―-<2D>―Λ<E28095>o<1B>zώw^—δΏΞ<CE8F><CE9E>λφ<CEBB>jλ_?{ώίέ/ΕΏ=ψΥΖKο―·ώ[σ?dωΪϊO<CF8A><4F>ωω<CF89><CF89>Ύω>ζΞ<CEB6>XύS«ς<C2AB>ύϋ_Λπϋν<CF8B>p<EFBFBD>#]<5D>aίΜϋ―ψωΓώ<CE93>ηοmο<6D>΄ϋ―»<E28095>±i<C2B1>χΠ_gώ?kύέOώγ<CF8E>Γ<EFBFBD>‡<EFBFBD>οSόΨπ?τ·Km<7F>γ<EFBFBD>ΧϋΚσ3Χ<33>yΏυ=ώ2ψµϋ—ύΏ½ρiόOΫώκΗ?<3F>Ώ³ώz>zβ?«ω<C2AB>[γo³μ<C2B3>γ–μτ?ω_<CF89>ρλχ<>–β<E28093>Ψ¶ν?βί¶ρ'<27>Οvόkt<6B>γ―χ™ωOuϋΏ<1C><<3C>ύΎwnL?Οέ<CE9F>¶<C2AD>_<EFBFBD><5F>ΧΞ¶<7F><C2B6>Gό<47>“όΏ+ϊ<>ήΉ<CEAE>κχ?Ν<><CE9D><EFBFBD><EFBFBD>Oώ<4F>Jφo―ύ'Ν<>Χ<EFBFBD><CEA7>β<EFBFBD>“³β<C2B3>ο·<CEBF>‰<EFBFBD>τ9κόύ„υ<03>ϊ―—ϋώξUO τύ1>ό>Ώ9πγρ__ιηπ·<CF80>ΏΤ<CE8F>)ΕΏ&<26>jψ_ν<5F>ƒί®<CEAF> ?τΧ¦ΏfύΓ»γ?cύ―[<5B>Ώξ<CEBE>ƒΏnύ7ψώ‡<CF8E>mβΟώη„ΓηήχήϋIαKΟώ―5ώ,¥<><C2A5>φ<EFBFBD>σΡ¶<CEA1>¤ρ_νυ―έ<E28095>fmύ_ΗΖϊΏs<CE8F>τ?ς<>
|
||||||
|
ω/“Ώσς_ϊ<C2AD>Π<EFBFBD>vτ?τ‡ώψ<CF8E>‘<EFBFBD><E28098>>η8<7F>Σsώ{FώυΊη<CE8A>η<C2AD>rώ<72>σ<EFBFBD><CF83><EFBFBD>ηό?η<>9<EFBFBD>ΟωΞ<7F>c<EFBFBD>Ϋ:<3A>OύoΫη<CEAB>9<EFBFBD>Cύψ<7F>ϊ<EFBFBD><CF8A><EFBFBD>·yώ<1F>ώ?όΦϊφΨ3ϊ<33>―{ώώΗώ·Y<C2B7><1F>ψƒΏέψύ_θ<5F>ύϋ<C2AD>τϊ―Q<E28095>Τ¦<CEA4><C2A6>ϊΏΤ<CE8F>Υζ<CEA5>;Ι?{υ?Kώ±<CF8E>!<21><>ώΟΨ<CE9F>Ψ<EFBFBD>Δ<EFBFBD>±<EFBFBD>‰<EFBFBD>#<23>ι<EFBFBD><CEB9><EFBFBD>ϊ[‰<>c<EFBFBD>Α<EFBFBD>Π<EFBFBD>ϊ<EFBFBD>Τ<EFBFBD>£ώγ*τ§ώεϋλ<CF8B><CEBB>ϋ<EFBFBD>Ηλ<CE97>P<C2AD>¥„Kύ=Ή<><EFBFBD>ϊΤ<7F>¶W<C2B6>ύOύGκΏΩ<CEA9>†ύ‡όc<CF8C>c[ώ―X<E28095>{<7B>ϊηΦϋ<CEA6>Τχsκ<73>―g<E28095>S<EFBFBD><53>ϊ<EFBFBD>Τ<EFBFBD>§ώΏ%ύΏ’<CE8F>ο<EFBFBD>υ<EFBFBD>Kώ―Ϊϊ›“<E280BA>ƒώG<CF8E>γ<EFBFBD>Η<EFBFBD><CE97><EFBFBD><1F><>»υ<C2BB>ο·?ΏΌάό<CEAC>υΗ΅άwώχιρ>ύSγ¥πSϊ/ώΰώ/IεΛχC>εδ<CEB5>Y~Jρ?δσοw
|
||||||
|
~<1D>ςψm;_<0F>Ώ<EFBFBD><CE8F>όΧηόόωφ?τ‡ώkΘ?/YώάϋΧvΏ»γ/•<>σζΏηχώ™<CF8E>m;<3B>O]wλ{&<26>§αΧπ©<CF80>O]χ<>ώ‡<CF8E>-σ?ψΫ¶<CEAB>Gβ?Ύ<>ξχ»}όα<CEB1>ύ?<3F>πGθ<47>IγeώΏtόΑ}_<>mϋ_<16>™Q<E284A2>v•ψOμοOΛΣψχΏίνγγί<CEB3>~―΄ώΫρχύξ<CF8D>υίo~~Ό}†ώΏ†~³<>ηέΟoGώϋρ«yϊΏ]ώϊϊ_Z<5F>ΑϊώO›ώ#σί>Ύ><3E>ΪλoϋϋΟΆύ‡<CF8D><E280A1>ψ<EFBFBD>„ώRό[θΧύΑόΰολ²ςηΤ_=ΎR<CE8E>Ο<EFBFBD>륤κ?ηρ/<2F>j><3E>ώί‡
|
||||||
|
ΏsΕ<17>»πωγώS-ρ«ψςψ—”ώ²υΏm<CE8F>ωο{ήσοηΏ1ϊλπΏΤώ<CEA4>a<EFBFBD>jΦΏ΄.<2E>µϋΏiΛY<7F>·t<C2B7>7/-ύοW<CEBF>u&<26>#<23><>Ψ<7F>λΨ<CEBB>3μΟϋ<>ώψKι<4B>ύ<EFBFBD>ύ<0F>Γ<EFBFBD>Ίόoτ?ώ?όθΫϊώ‡<CF8E>α;όo=<3D>‘ρ<E28098><CF81>ηό<CEB7>xώ¤tύiη’<7F>ύ5αίρόΛΜσ?λ<><CEBB>³yώΥ§WΨ<57>=½?ΘΣ_<CEA3><5F>ί~ώΏ¶?κΉNώ<4E>¬σoιο[Ξ<>qώ…σ<CF83><7F>g<EFBFBD>ΓώΧΦxΞ<78>P<EFBFBD>‡σΧθ?Ξ<>#<23>ρ<EFBFBD>ΰ<EFBFBD>ƒώ¶όΨπ?τ§ώυ<>¬Χ<CEA7>W¤Η<C2A4>yΗυ?<13>•κ<E280A2>Ιβ?cρΏuκ?¥ρ―ωίηΥ<CEB7>Ρρ<CEA1>KγgσμO<CEBC>ψρτ?υ<>©<EFBFBD>GόϋΟΆύGόωOώ<4F>έψΧΘώοψέάϊ―:ύ¨<7F>Oύς<7F><CF82><EFBFBD>γ<EFBFBD>Υρ<CEA5>S<C2AD>_<EFBFBD>¤ρς<>Ι<EFBFBD>ΧΝ<CEA7>—Ωcω<63>λΤ<CEBB>Η<EFBFBD>O<EFBFBD>Okρ<6B>Χ½θαγ<_ϊΊγ<CE8A>Χ<EFBFBD>ά·ιλµϋΗγ¥πkχο}>π<07>ΟΕ<CE9F>U‹$¬RώΎ¤ψ<C2A4>_!ΌώµρυWί~ψ½χ‡ώΠ_‡ώΪυο<>Ώtύ―W<E28095>ΊV<CE8A>κ\λjώ:υίΰψώ·‹Ώuϋ<75>πΕόύ„ώΛ|ηίzω<13>ϋ‡γ<E280A1><CEB3><18>γϊ™ώ―ίΟ…Ζ?„ύ}ϊoΫΉ<CEAB>MN_Ε}n¤τΧ¶<CEA7>[π―ΏάΌΔφ<CE94>ϋ><3E>OΝυ―έ<E28095>f…υ/Α†ό»s<C2BB>τ?ς_ΊώΓΎi3δοYώ§ε2ϋ?τ?ϊϊΫ¥?ώβ?Uϋ‡λ\'ώ<>΅φ<CE85>Hό'ξ_2~ώrLώφ<CF8E>/Ϋ3²ώ/RωΟψ_}κϋ<CEBA>ήω—<CF89>??ΏζϊΣ–οcώ—OΫχΉρe<CF81>Ώ|δ<>Θώ/άΟHη_Wώ<57>μ<EFBFBD>ΒυΧ2εύίέψo<CF88><6F>›ψ'ρOμ<4F>»εΏ΄ΧOmΛ<6D>Ρ΄t<7F>_{ώΙ<CF8E>#<23>ώ'<27>Ο<EFBFBD>ό³ξίΕ<CEAF>‡<EFBFBD><0F><>e<EFBFBD><65>Μώ›‘<E280BA>―<1B>‡<EFBFBD>±<EFBFBD>±<EFBFBD>µΞ<C2B5>άύόψƒ<CF88>gα<67>^ύ―-<2D>¥ϊ?
?ό®Ύ‚ώΠ_‹ώ<E280B9>ϊ_ΫvώώωHΧ—z><3E>υ¬Φ8<CEA6>2V<32>j<EFBFBD>ό—Β—ΦΏ=Σ?δ<>4<EFBFBD>¥υΟ|HΑkΕΏ4Ύτw><3E>Uβ<55>–υχzOρ<4F>σqζνυ―Ν<E28095><CE9D>#<23>Ζλ<CE96>=sη?5Ώώό§λίΩ”Ψ<7F>κρgΖί6ώ<36>ύ<EFBFBD>9ϋ?i<>΄+ϊ―½sύ[ΧΪτ³Ύώξ#<23>ηΕ<CEB7>µγΏΘθΏ|μ?μ?ό<>Π<EFBFBD>ύώ/ϊ_Ϊξ<CEAA>H<EFBFBD>W‹λ<E280B9>ώ?τ<>΅<EFBFBD><CE85>Υώ?Θ?τΏ¬ώλΌώΏΪςίz<CEAF>_μ?δ<>=ω‡ό<E280A1>Υ<EFBFBD>zΜώ_gύKϋοJι<CEB9>ώΏιύ<CEB9>T<EFBFBD>λΨ<CEBB>θ]ώ<>ω'Υ<>:ϋλςύ―λ<E28095>+η?<3F>Ιί™ω<E284A2>νϊGκ<47>A<EFBFBD>£<EFBFBD>ρ<EFBFBD>γ<EFBFBD>Η<EFBFBD><CE97><EFBFBD><1F>ψƒ?ψ_<CF88>ΏτόΣ<ω―£<E28095>Λθ<7F>ώ<EFBFBD>γ<EFBFBD>iί<69>®δ<C2AE>³ξ<C2B3>Βώ‡<CF8E>αόίΰOώw«<77>qίC<CEAF>cλψ\όKώύ?i<ωψ<7F>{γί9~m|.ώΏΖϊ'ώ/ϋ,¥ίμηyχσΫ‘<CEAB>n=ΟΤ<CE9F>νςΧΧ<CEA7>ΫΦώόΉϊs<CF8A><73>Π£<CEA0>Θό·<CF8C>―ΟΏφϊ[ΗώΖώ³h<C2B3>α<EFBFBD>Η<EFBFBD>GόόΑίzό_<1A>σ/―#<23>mζ<6D><12>c<EFBFBD>ΗωWβ?μ<>8<EFBFBD>ΟωδφΏUόΙ<CF8C>!<21>ϋ<>ό?ψ<>ό?ς<>π<EFBFBD>α<EFBFBD>Γ<EFBFBD>‡ώ·sώώ‡<CF8E>α[ό<>zΆ=|ό<>ηγ:ΧΟΧ<CE9F>ό|ύΟ}›Ύ^»<^
|
||||||
|
Ώv<EFBFBD>ήηϋlό_½HΒώ'=<3D>¥λKzισχΓ<CF87>η―φ<E28095>έϊί‹ώsαkΚwyώ·<<3C>ωλλ•Ομ<CE9F>Ο=Ώ<CE8F>π<7F>λµρΗυ3ώ²όW©ό_©<5F>“λ_<CEBB>ο<15>~ώόΏ»<CE8F><C2BB>ΓΧΗ?Η<>©υWο_<CEBF>ω_ύKσ?dωΪϊO<CF8A><4F>q<EFBFBD>pώ<70>yn<79><6E>ηcξό<CEBE>Υ?µ(<28>°<EFBFBD>ΩίZΏήoΏ†/ιϊ<CEB9>ν—ϊχ_εηνί<CEBD>}ξώO»<4F>°ώώΗΊύ―K?λλο<CEBB>ς<1F>ώ?ό<CF8C>ΰ<EFBFBD>Γώƒ<CF8E>΅Ώeϋ_ί<5F>¨ ίΊύ76<37>σό<CF83>χ\<5C>sύΏ<CF8D>ώ<EFBFBD><0B><>^όG<1A>Σ¶ΏΖπηίΕ‘<CE95>?–<>¥ψΟZώ<5A>ΎψΩόύ<CF8C>{γΔ<7F>Ρ<EFBFBD>–γ?-ροX^ΕςL:<3A>ΪςίzόϋΟ®ύGόωOώ<4F>έψ—d<E28094>γτΏDώϋ“mk·<6B>SρΟ<CF81>ψΰzτ<7A>ύ?w<>·Ϊώ<CEAA><CF8E>όΟόgλωΔ<7F>?Ι<>«ι<C2AB>Σί<CEAF>ψ<EFBFBD>ζΕΘ<7F>'<27>µό<C2B5>ϋoFώΏfό<17><><08>Μ‹<CE9C>λΨ<CEBB>Δ<EFBFBD><CE94>ρGΙψύ+σΚύ®6Ύφ=π<>όχΓOϋ<1F><><EFBFBD>|‰ύWΓ―αί¶<CEAF>.ϋ?4αCθ―M<E28095>sύιΈ~µϋ<C2B5>Xύλ|ύι»γχωOο?βύ›σΔϋ<CE94>9ψηαΧρoΩ–φ?π?όo<CF8C><6F>νβΟώ#
ίϊ»υύ<CF85>σ/–―KηyUϋΏ?νω›1<E280BA>iωλδl|ύω<CF8D>7~]ύ/{ώ»Μ?ϊωΏΆό—όe<CF8C>‡ώ·®<C2B7>΅?τΗ<CF84>oYώΫ><3E>ώγό5<7F><01>zψ<7A>ωqήά<CEAE>σηόΏt^^:<3A>ΞΗ«<16>jΛ<6A>λƒί›<11><>=<3D>“<EFBFBD><E2809C>φόΛώιό?χΌ<CF87><CE8C>©λΏΠ~έwΩώΊv<CE8A>ηc.ό}<7D>µ<EFBFBD>· <20>OλΏϊω,―$τΧ–<CEA7>5|kλ/7/σΉβϊΧΎ®Νw<7F>?δπ―;<3B>;―<>Η=Ο?<>ωίΦύOzΏ2gύ<67>οΏ<CEBF>φj|Ιώ?ΓΟ<CE93>o³<>Λφό―Ν<E28095>γϋο+ΦΏφώί<CF8E>ό£ώ'ώ?όψ<7F>μΦ<CEBC>·<>f¬?mϋώΗώ·m<C2B7>«―?ΰψ7”<37>οƒ<C692>ό_
>τ‡ώτ?Ώ<>ύΌσz<1C>Κ]ρ<>7>|?Ξ•Έωwµ²όϋ_5<5F>ύπΛγύο·Ν?7“¥Oηϋάωχk#<23>ΰ<1F>―}ήδπ«ΏΦρΉΟk¬mώΏ<CF8E>ό»ϋό[—vνέψ<CEAD>~όΫ:ώΨ<CF8E>¶ν<C2B6>}ε§[?~}Ψqωλί<CEBB>χ;Ό<>:λί®ώ›C©ό›·ώβρmψ£<CF88>tβ<74>Ϊρ_δΏuϊ<75>Χo£<18><>ϋ`<60>a<EFBFBD>α<EFBFBD>‡ώzτ_±ώΤ=κ_iΧίΌΎυω·΄ώ¥ώcι»nύg9~R<>Ώφ»Δ<C2BB>0―ώx~ό?<3F>µώ<C2B5>χ¬?δϊgµϊ<C2B5>ύςK<CF82>΄ε
|
||||||
|
<EFBFBD>ρηηόΑΘ?δπeπµίµΧψήj^5<>ύπΛγKίΟΩ<CE9F>ΝέjΫ<6A>φτ<CF86>Zό?ωwχω·+<2B>Ψ<EFBFBD>η<C2AD>{§ό<C2A7>£¤ώτ?ϊ<1F>?ώό<7F>ψ<EFBFBD>ι|ΰ<03>ώοτ<CF84>ώΠ<CF8E>ώίτ<CEAF>~oόΏ-<2D>tώΊφ7ό<0F>Ϋζϊ<7F>Ϊήμ{8ΎφΉχ½χ~Rψ<52>ίΗΛ}›w<7F>Ϊύζΐ<CEB6>ΗΣ<CE97>—ώ―¥ώσ®_Π±~ΒψΑΎΛβρψ:<3A>ΏsύKβ'sζ_;ώ“£<E2809C>΅?<3F>λ£ϊ?/<2F><>Οί?<>γρ5ύo]ώ<>χ<EFBFBD>“κ<E2809C>Z<EFBFBD>²<EFBFBD>>ΏΊ<CE8F><CE8A>ΥώΟΪτί¶¶υu<7F>Λ±υΧή<CEA7>PΫώΕώΓώΓ<CF8E>Oό‡ώ‹ΐΎΥώ<CEA5>τ<EFBFBD>΅<EFBFBD>ύ¬φ<C2AC>΅<EFBFBD>µmω_ο__~—ΞΏ6<CE8F>IρΣ<CF81>?ψω‡όώ]ϋ<>έ<19>OμΏ<CEBC>ύO<CF8D>Oψί.<2E>[Γύ<><CF8D><0F>ϊύ<0F>Γ<EFBFBD>πΏ%ώ·<CF8E><C2B7>ώ<>αό<CEB1>Ύ—σ'<27>οFσΏΚωίϊω<CF8A>δ<EFBFBD>Ϊ¦<CEAA>ΎΟ…ΣίCψξώk<CF8E>YοόΟ;σ<>9<EFBFBD>›λ<19>JΥ/›‘<E280BA>_κW?<3F>#οg=<3D>_σόΩΊη<CE8A>-<2D><>γό?η<>Ω<EFBFBD>sώ<73>σ?6λ<36><CEBB><EFBFBD><EFBFBD>n“ΏξώΎΝµΞώϋ<>σ<EFBFBD><CF83><EFBFBD>Η<EFBFBD>‡<EFBFBD><0F><>=<3D>φηΏ΅ΏMϊS<CF8A><0F>Η
|
||||||
|
uHVσΏYy—Ζ¤ρΏμ?i<>'ιω»Uκ<55>εγgΗυΡϊίµύ<C2B5>zρ?+φ?ϊ<>ό/κ<>Ω<EFBFBD><CEA9>c<EFBFBD>Ω¶<CEA9><C2B6>#<23>Ι<EFBFBD>³<1B>’φ/<2F>³<EFBFBD>\―<>υ<>©<EFBFBD>Oύβ<7F>β<>+ϊ<>ήY<CEAE>_Άζ<7F>%<25><>όMϋwN<77>ϊQύ£<1D>Ε<EFBFBD>O<EFBFBD>O»ω!}<7D>ηΛΡ<CE9B><<>g<γο?>®K’®<E28099>r®<72>ς.ψW?Ώ6|θύuεΗωύχϋ<CF87>Χο<CEA7><CEBF>½η_ϊ'η<>Ϊύ―}~ψώ·Μ<C2B7>ΰoΣώΏwύi9|θ―[<5B>U[<5B>κΧ]…<>Βχ<CE92>ότΒ/<2F>χΏ_IώΞΓ<CE9E>ξσ<CEBE>ώGώkΤ<6B>Φ•ΏΦχθτ?τ·Kό<7F>ψ<EFBFBD>άωΞγ|bξόηόxΌ;<3B>•/…<>Κ<EFBFBD>βί<CEB2>/<>p―Xϊά<1B>ρΗΏrQ<72>υ™–<E284A2>ξχνλΏ4ΎMώKγORω―·<E28095><C2B7>C™όΫ¶6ψ-ρΏ–η=<3D>~ήϊKΩΜξώώyύ<79>Nω/«<>ΠfΊϋ<CE8A>ι_Ξ<5F>ƒί“<CEAF><E2809C><EFBFBD>'¦iύ<69>ν<EFBFBD>JτΧ–<CEA7>γψ·ο<C2B7>|όcώΧ^<5E>ΦγoΔ?±±<7F>Λφy‹ύ%µ<>υχ<CF85>Rό¥ϋ<C2A5>yσ<79><CF83>_ς<5F>Θ<EFBFBD>ƒ<EFBFBD>Ι<EFBFBD>λ§Ο§Λ?όίψ<CEAF>π<EFBFBD>α<EFBFBD>³θ<C2B3>›g<E280BA>IΟ<49>hΗνς?φ?ηΟxΖsώ<73>ό/Ξ<>C‹ωί:ηOΦ‰Ωτ<CEA9>εθ_Ϊ+§~'Ο?Φ±<CEA6>Ι<EFBFBD>ηόη<>8<EFBFBD>Gό<47>όΛω<CE9B>Ψ<EFBFBD>Δ<EFBFBD>‰<EFBFBD><13>'ώo[<5B>Υβ<CEA5>#ς«-ώ«<1D>ηό§Uϊ<13>ΗώΓ<CF8E>ύϊ<C2AD>µϋΟhΒ?Ζ»οb<CEBF>ρυΟo}ώ―©<7F>Ω<EFBFBD>#ωύh]ΒλρχeωU§ίΥώ<CEA5>3ύ<33>?υω«Ν³|ώΗόRώkΏϊοZ<CEBF>Νυλω‡ώΧ¦Ώ$ώ,<2C><>uδΏV<CE8F>1ψω‡όcΌφϊΧ±?ΧY<CEA7><59>?)ύtώζν<CEB6>¤ϊ_ΗώG<CF8E>λς<CEBB>ηΘΏ»ΟΏMω‡ώΧυ<CEA7>iΛίyϊGκ<47>A<EFBFBD>£<EFBFBD>ρ<EFBFBD>γ<EFBFBD>Η<EFBFBD><CE97><EFBFBD><1F>π<>όwκ<CEBA>ψΟ
|
||||||
|
φφτΗ<CF84>gΣ<67>oέ<6F>§½<C2A7><C2BD>·<EFBFBD>ΊΆώό<0F>><3E>ƒΏmϋίΓρΗw―Ορυ~ξωKγχ½<^
|
||||||
|
?<1E>χS<1E>Γ<EFBFBD><CE93>Ώγϊθό»ϋ<1F><>ΑΘΣ_
|
||||||
|
??bϋό^ν<>ϊΧζEϋ_ϊόο<CF8C>?ιxΗ/m<>{ίΫξ§·ώGρ<47>K?½χ}~ΏΟηιGτ›ό“ΒΟ<CE92>―ιλς?Χ<>/<2F>ΟqωUΣ<55>Ήώgϊ??ΎMώZί<5A>J<C2AD>–υ?£<>έΎΟ]ΟGyώάύΦ°±<7F>lΫψ<7F>ρ<EFBFBD>ψΐηόΏµό_λωΔ<7F>Π<EFBFBD>Ϊφη<CF86>γη±<7F>³³<C2B3>ƒ<EFBFBD><C692>μoλπΙ<CF80>!<21>ϋ<>ό?ψ<>ό?ς<>π<EFBFBD>α<EFBFBD>Γ<EFBFBD>‡ώηό?ό<0F>Γ<EFBFBD><CE93>Λ<EFBFBD>__―|,?<3F>ιθΟςz<CF82>γ»mσύ›<CF8D>ξχΊΎmαψ<17>ώψγϊΡ<CF8A>Δυyύ~.όxΌ»~Τgπηό<><CF8C>ςσ»QcψeψGΏ#ΧΏΨυ':ϊ!Ή~Ea<45>γλ?μ›|†_[<5B>ηη<CEB7><CEB7>?μΏ<CEBC>ϊ>…—ƒ_<C692><5F>άΌ΄Β‡ώΪτίχΉπc8ξώ©ωΤ–<CEA4>ςόoYώs
|
||||||
|
<EFBFBD>πz¬<EFBFBD><EFBFBD><EFBFBD>Ύρgώz>ζδΏΞΰ?ύώοηυΪΣiϊϋπΚτ9ΫW¥ω/υίkΑ?έ<>ΟρίσQη<51><CEB7>Jψ¥τGι~ηϋ―Έώ¥ηgΪΗkλΏ+<2B><>Nσo]ώ±<CF8E>`<60>o<19>Ϊώ§΄_<CE84>³<EFBFBD>ΠέYί<59>εν<CEB5>s<EFBFBD>α1ωλοβώΟ+μ°<7F>Gι?Cώ•Ξ<E280A2><CE9E>ΏΎσΏΘόψ<7F>π<EFBFBD>Yυ<59>a<EFBFBD>Yηθo™ώ5<CF8E>lΏ<6C>±Ο<C2B1>«ν<C2AB>Δ<EFBFBD>!σ_^q]Ϋ<>¦<EFBFBD><C2A6>;―Kγ?<3F>ψ<EFBFBD>¶ύw<CF8D>?¥ςΡςώσzό§ό®ο<C2AE>ίχ‘ψΫ,ϋΕψ<CE95>%ϋύOώWOΌzΫζΖ<CEB6>Wά<57>[<5B><>c<EFBFBD>Ω¶<CEA9><C2B6>Ϋ†Oώ<4F>νψΧθώ§]<5D>χε?½ή<C2BD>¶ξ<C2B6>¦Η—μ<E28094>ηCbίHχ«ν<C2AB>WΰύψΏ¥ό?β<>–ύΏ+ϊ<>dϋ―}—ψίzτΟ<CF84>ψω<>δ<EFBFBD>―”<E28095>ίk<CEAF>Iυ<49>vό<15>‹όKΟΧω<>ΧΫ<CEA7>Δ<EFBFBD><CE94>λG½€ψύ+σΚύ®6Ύφ=π<>όχΓ—Κ<E28094>«αΧπΏΪ<CE8F>z5|θύµι―Yθξψί}ώ¥ώ‡9ψλΦί‚<CEAF>αΫόoφiψΦίο<C2AD>ZύΗ<CF8D>y^ΥώoΕO{ώfΜΏf<CE8F>™uυΏμωο2<CEBF>θδ<7F><CEB4>ς<EFBFBD>]ς—ύϊίΊώ‡ώΠ<1F>ΏeωOύ?Ξ<>sώ†σ?ύηΏgΤ<67>[σό?ωΏ<CF89><CE8F>ηό?η<>9<EFBFBD>ΟωΞ<7F>sώ<73>σ<EFBFBD>ΨίΦΞ<CEA6>[©<>ΝωΞ<7F>P<EFBFBD><50>ϊ<EFBFBD>Τ<EFBFBD>ηό?η<>ρ<EFBFBD>α<EFBFBD>Γ<EFBFBD>g©<67>ηΈύ7cύyώί<12>c<EFBFBD>Ϋ®<CEAB>|ΰίnό‡ώ/τ<><CF84>ώvύλυ<CEBB>~oύSλώ?κ<>Ϊ®<CEAA>»<1E>ίIώέΏώ―mωΗώƒόΫύ<CEAB>±<EFBFBD>‰<EFBFBD><13>'ώOόί¦ό·ή<C2B7>έΊ<CEAD>Ο:ύmΗ<6D>±<EFBFBD>π<EFBFBD>Cκ<7F>σNύGζίΦϋ<1C>±¬ώ<C2AC>vύ—ώ£Οίη<CEAF>Χ®<CEA7>Gύo«υΠχΤ¤ώ›έϊoπσΝώΗ¶ό_±ώ·~ύsλύΪφΧν?uνκ<7F>S<EFBFBD><53>ϊ<EFBFBD>Τ<EFBFBD>·΅<C2B7>Χσ<CEA7>½³ώΏD<CE8F>Μρ?Ά<>Ρ<EFBFBD>ψ<EFBFBD>ρ<EFBFBD>γ<EFBFBD>Η<EFBFBD><CE97>nύθ§β9<CEB2>―Η<E28095>g<γΧρ΅|?δSNώ<4E>εηµπ―~mψΠϊ―!?΄<>ξ<EFBFBD><CEBE>=ηίΟσ{Λυyό_»<5F>5Ο<0F>Γ<EFBFBD>–ωόmΫ<6D>ξό§σΈσ“ώoΖύΟξώώ™ΛΌ<CE9B>[
|
||||||
|
?_ς<CF82>~ϋχ½ςπΗζ?ογ<CEBF>/…<>ΒΏDΙωciόA[<5B>κϋυγ?ϋϊϋέϊρωΓύίχ;<3B>~—ΏχΗίΗχΧ^<5E>?εη<CEB5>qIγ?><3E>sΰ—Η—ξ[Άw<CE86>^νϊ³MώIαKoWώKκΜΠ<CE9C>ωϊuύ/<>`}<7D>§M<C2A7>Τόυ¬<CF85>ςψ6ύΏοsΧ__ύ]ϋϋΟ¶ύ‡<CF8D><E280A1>ψ<EFBFBD>xώΟxΖίzΌτO‰λΆ¤λ?—<>Ώ<>Ό<16>N<EFBFBD><4E>Ύ<~%<25>)ύ―]W?ΏφϊΣβ<CEA3>υκΟΏΎuω―έ<E28095>M›<4D>τϋΐΘ?δγµΗλΪ<CEBB>χΗ<CF87>ήσ<CEAE>ύoΣώ‡<CF8E>απG<CF80>γ<EFBFBD>Γ<EFBFBD>‡ώ·«<C2B7>αψώ·Η<C2B7>ΦσΑ<>σσΦΟ<CEA6>»όΞtώdx½?©΄ώµσ?Ι<>‚ώyόΗΰΗτ<CE97>ηΟΟ<CE9F>]'<27>_ηόΟ
|
||||||
|
η<EFBFBD>,<2C>υιύ|<7C>ιοΦ―ϋΏ_n^ώΏ{ο9<CEBF>S_Ϋ?<3F><>―ώLϋό‹υσ<CF83><7F>·½`<60>oΞ<7F>P<EFBFBD>gΞωοφσΨ+<2B><>G<EFBFBD>qώίΊόΗ<CF8C>‡<EFBFBD><0F><>M<EFBFBD>φόύ©<CF8D>Bύ?»υ<C2BB>4λ<34>¬γ<C2AC>Υ«Ώ·Jύ?Yόg,ώ·Bύ§ηγόήκ<CEBA>W<EFBFBD>GΗ<47>Σ7E<37>ψzoύο6ϋ_'ώGόύOύgκ<67><11>Ηώ³h<C2B3><11>Fώ[Ο<>³<1C><>νbϋy$<24>―ώ¨N<C2A8>κ<>S<EFBFBD><53>ϊ<EFBFBD>Δ<EFBFBD>©<EFBFBD>―γ<E28095>[§ώΏT<CE8F>Hγ?δ<>“<EFBFBD>―Y<E28095>_j<5F><6A>ϋ<EFBFBD>Χ¨<CEA7>oΧ<6F>O<EFBFBD>O«ρ<C2AB>Χ“Όd†ο?=δSϊΊ{ώΧ<CF8E>ά·ιλµϋΗγ¥πkχο}>π<07>ΟΕ<CE9F>ίo_ΫΦφ9|Iρ?ΏBx5όkγλ―2Ύύπ{ού΅Ώύεωί²ό‡»γ/]<5D>mρλήω—δΏΏΦη±ί?Γ?ΧΊ<CEA7>ƒ<EFBFBD>¶µΑo©Ώ<15>ΟΧί‚<CEAF>αψί.ώΦν<CEA6>Γίωχϊ?sπ<73>λεO<ξ<1F>>bό<62>λgϊΏ~?ώ<19>>τχιθKΧΏ&――β>7RϊkΫ<6B>-ψΧΦ_n^b{Δ}Ξ§ζϊ—ηΚβ+¬ ώ3δ_)ώ96<39>½ρOτ?ς_Gώ<47>ϋ¦Ν<C2A6>Ώgω<67>–Λμ<CE9B>Π<EFBFBD>θθo—ώψ<CF8E>‰<EFBFBD>Tν®s<C2AE>ψ<EFBFBD>‡Ϊ<E280A1>#ρ_<5F>μcωί+ϋΖ—ν™^όΟϋG‰όΏgό―<CF8C>>υύοόKΖ<4B><CE96>_sύiΛχ1<CF87>ΏΛη<CE9B>νϋάψ²<CF88>_>ςd<7F>ξg¤σ―+<2B>Gφαϊk™Ώςώοnό7Ο<37>Mό“ψ'φ<>ές_JφWΏύ―k<E28095>θ>Ώφό“<CF8C>GώόOώ<4F>UωgέΏ‹<CE8F><0F>ώ?Λώ?™ύ7#<23>_7ώ<0F>c<EFBFBD>c<EFBFBD>k<EFBFBD><6B>Ήϋωπ<07>ΟΒ<CE9F>½ϊ_[ώKυ~ψ]}<7D>ύ΅Ώύ¥υίό9ΜΥσοίW<CEAF>ο<EFBFBD>η_Ζϊ_Μ“<CE9C>Rψ<52>ϊwgϊ‡ό‘¦³΄ώ<CE84>Ο)xψ—Ζ—ώΞηΏJόί²ώ^ο)ώ>Ξό―½ώµω<C2B5>sδίxύΗηcξό§ζΧ<CEB6><CEA7>t<EFBFBD>›ςϋ_=ώΜψΫΖ<CEAB>±<EFBFBD>?g<>W•Ώ_Χ^<5E>Φυ<CEA6>6ύ¬―ΏϋΘ<CF8B>yρνψ/ςϊ―ϋϋ<0F>?τΏ<7F>Λn<CE9B>_ϊ?ιΡ<CEB9>ώΧϊύ4ϋΣ<C2AD>9<EFBFBD><7F>αΌώOσϊ/¦ϊe•ϊ<E280A2>HόRω§έ<C2A7>«l?<3F>Ώϋω‡ώ_ƒώcρηyύ<79>΄εΏέώΨΘ?«ςω―Ϋ<E28095>{<7B>υo³<6F>5ύΡ<7F><CEA1>ό<EFBFBD>9ςO<CF82><4F>uφ<75>Φεϊ_Χ<5F>WΞ“Ώ3σ<33>Ϋυ<CEAB>Τ<EFBFBD>ƒώG<CF8E>γ<EFBFBD>Η<EFBFBD><CE97><EFBFBD><1F>?ώ/+ώOπ<07>5πΧ‰<CEA7>hΫ<68>ΨΠϊΫυ<CEAB>[χ<>iο<69>kη<6B>Ϋχ_cη<63>αψώμ<7F>σψΧηψϊΏ<CF8A>;ψ<><>7<>ώψίοφρ9ϊ―<01>¬<EFBFBD>ώ~RΧCϋ?µ~<7E>~ϊζUϋ?χό?εη>ΚσηξWζ<57>Vψµρ?ερ9ω<39>ήΟΪλΏύyΣογλ<CEB3>οgόyΏ―ιί΄=7ώϋΰΧΗημOδ<CEB4>ό<EFBFBD>εΧύΫ.ΫΗχ<?ώΏΥθί²ώ·έ™›<E284A2>5Φ<35>¶ύ‹ύgΫώΓ<CF8E>Οωόΰώ<><CF8E>·“<C2B7>k=<3D><>ψϊίηΪ<CEB7>cώ/mϋ—ό/φ–χλρ?ςω‡ύOώω?Ψ<>Ψ<EFBFBD>π?όOώωψ<7F>π<EFBFBD>΅<EFBFBD>Ρ<EFBFBD>π?ό<0F>Γ<EFBFBD>Rώ<52>ϊzω£|ό<>η{qΚρέ¶ωσσο~ΗυΪψγϊQ_ΑΗψwƒ<77>|„π·-ΐi…<69>|Μ…<1F>wΧ<77>ϊΎό·<CF8C><C2B7>¶<EFBFBD>ϋo[ΨΕοWμ<57>~Ζϊ«Α―<E28095>–ηχ<CEB7>·„Oόpώ·νά<CEBD>9μS†ύοF<CEBF>Ήπµε<C2B5>uωσmγSΟ<53>Ξλ’όΧς•ώοώϊMΩΣ1ύ|x3ηΏΤλΌ~¶}όσqξΏ•ζ<E280A2>όjγ¥χΧ[<5B>ω²όmύ'Ε<>όόΟGίό?sη?<1E>|”ΗΫ–μΨ<7F>Z†ίo<CEAF>‡ϋιϊχο7g<37>?ΏΟ<CE8F>q<EFBFBD>NφύςΏlυ<7F>Ώ\w<>cΣώο΅ΏΞόΦϊ»<CF8A>όΗ<CF8C>‡<EFBFBD><0F>ί§ψ<C2A7>°<EFBFBD>ΰθo—ώΪώΗ―[χ?”ηg®<67>σ~λ<>zόeπkχ/ϋ{γ?<3F>ψ<EFBFBD>¶ύΥ<CF8D>8gύυ|τΔVσ<56>·ΖίfΩ<66>+Ζ<>,Ω<>θςΏ4γΧ+ξ<>-Ε<>±<EFBFBD>lΫΔΏmγOώ<4F>νψΧθώΗ_ο3σ<33>κφ9ώyϊ<>|οά<CEBF>~<7E>»<EFBFBD>[m<>Ώ<02>―<EFBFBD><E28095>l=<3D><>ψ<EFBFBD>'ωWτ<57>½s<C2BD>Υο<CEBF><1B>!<21><>ό<EFBFBD>•μί^ϋO<CF8B><4F>―<1D>Ε<EFBFBD>?&<26>fΕ<66>ίo<CEAF><13>?θσzΉzm<>{_½χ“Β—ώόΑίώ±|‰εsϊz,?Ζρ?δΣρ<CEA3>~
<0A>Ϊψτuχό5όΗΰχήϊCϊ‡ύέψ\ύ΅sύ WKκ|ίάψuδ<75>ιϊOΟ<4F>tώSυ<53>~ΏΣγCϋϊX<CF8A>9<EFBFBD>Cμ?<3F>γΨηΏί)ψuόΛγ·ν|έ~ψώ·Ν<C2B7>¶ρ·n<C2B7>υ<02>~Βϊ<CE92>9ψαο^υKίγΓοσχ›<03><>ϊΉ Ώ4<CE8F>EJmϋΏ†mύIύ<49>Ϊλ_»ώω
|
||||||
|
λ_‚ΏtύλΧE<EFBFBD>#<23>υδ-ώ1&Ϋγμ<>Π<EFBFBD>Φυ?τ·Kό<7F>Δ<CE94>τη:Χ3ό/]<5D>mόΫ<1E>:ώηψΟ¶•ς―Ξω“#ρ£πωJυfZζ―6Ύ\Ο¦<17>sό¨ώ<C2A8>Α―Ε―ςπ¥ρ/)ύ¥ςelώ%γΟΟ―Ήώ΄ε»υσΘέϊϊς<CF8A>ϊ<1F>η<EFBFBD>WX<57>–Οc<7F>c<EFBFBD>KμχφΏ®ύ£ϋόΪσ?f?‡»Ιϊwϋ—mΩµ<7F><C2B5>Οό΄οΟZψO²<4F>ƒ<EFBFBD>οΘ<CEBF>σδ<CF83>zϋ[ςΟΊ<17>ώ?ό–ύ2ϋ/½ώ\υ6ώ/σKΏύu><3E><>{Α<>Ψ<EFBFBD>Ψ<EFBFBD>γφ―”<E28095>οi<CEBF>‚?ψ*ώοΥ<CEBF>Ϊς_<CF82><5F>ΣπΓοκϋ'θύµθοΞΏΔυ®^4τkd…υ—^ηVό9τλKύ~<7E>ΗίϋχΧ®γ?_κΊ[ί3εΏ~~||έ_ΆΘi:§ζίΡΏ^Ση<CEA3>ΌVόKγK²ϊ<C2B2>ιϊcn^Zκ®R<C2AE>Q‡<51>?Gώ<47><EFBFBD>xήfΜj~ύω<CF8D>ωΗ²όΓώW<CF8E>?3ώ¶ρμ<7F>ΟΩ<CE9F>UεοΕΧµΧΏuύ§M?λλο>ς^ό_;ώ‹ό‡ώkΑΗώΓώΓ<CF8E>ύίο<CEAF><CEBF>¨<EFBFBD>uχϊW<CF8A>ϊ§ϊυ?µιoνυ/υϋq¤Ώ<C2A4>σχώ~λο§Χ<C2A7>uύη:ώ©xείΟ\<5C>ΏΏ^ψ©ω<C2A9>Η<EFBFBD>~§ι2Γ<32>/•5<7F>Eκσοχ»ό<C2BB>cλ―ΗώAώ΅<CF8E>Χ <CEA7>XόYJ<59>uδ
|
||||||
|
<EFBFBD>ϊϊ›'<27>µυ?φςΟ<CF82>όCώ‡φωϋ³Ηώ_gύηνΝ’ύ9<CF8D>ώRψcΏ<63>·<EFBFBD>“κϋύ―Λ<E28095><CE9B>#<23>¤ϊ_g<5F>o]ώ΅<CF8E>uύεόη1ω;3<>Ώ]<5D>Hύ?θτ?ώό<7F>ψ<EFBFBD>ρ<EFBFBD>Σ<EFBFBD><CEA3>ώοΰώτ§<7F>τ‡ώτ<CF8E>¦<EFBFBD>χ5ώΩωW9ώΊϋ?ψώ·Ν<C2B7>τ<EFBFBD>µl<C2B5>ώΒΎώ“η~<7E>µρΉώ<CE89>Ϊπ¦<7F>+ύϋσί=CύQ<><7F>¬°ώ%ω3ϊ<33>ί/<2F>oζόΛΰk?ΏMως³D<C2B3><44>Ι_wΏ«ϋ<C2AB>}ώώO—ώcσί>^Ϊ<>ςκυ§m<C2A7>b<EFBFBD>Ω¶<CEA9>π<EFBFBD><13>΅<EFBFBD>#ψƒ?ύ?ι<>C<EFBFBD>ϊ<>Xλ<58>C<EFBFBD>kΫςί[ϊΧϋυκύ:χ3ϊΏλΚ<CEBB>:ώµυ—›—XΉοΓωΤ\<5C>Ϊό<CEAA>όCώa<CF8E>Ϋν<CEAB>wwό?―<>7φ?ύ?α»όoτ?ώ?όθτ?ό<0F>Γ<EFBFBD>Φψ<CEA6>|x>sώ<73>σ<EFBFBD>£ω“<CF89>υ¤<CF85><C2A4>IώτΧ„Οσ/σΞ<CF83>θη?[?<3F>;R<>ζω<CEB6>‘ϊ[νγλυ·Θ<C2B7>Χ¬ΏΒωΞ<>qώ<71>ύϋ[‹<>9<EFBFBD>CύΛη―±<E28095>9<EFBFBD><39>όΗ<CF8C>ƒ<EFBFBD>ϊ[τ<>a<EFBFBD>Α<EFBFBD>Πί.ύ©<CF8D>gϋσΨόΟσήsύΟΓ¥ϊ#ρiόo…ϊO’ώO3Ξ<33>ιϊ<CEB9>eρ3ωώ_7ώgέώG<CF8E>Ϋ<EFBFBD><CEAB>P<EFBFBD>ΟvόϋΟ¶ύGόωOώ<4F>έψΧΨώo^ύΧϊΏR<CE8F><52>ϊ<EFBFBD>δ<EFBFBD><11>·Z<C2B7>_Σ<5F>§½<C2A7>’φ–<7F>%<25><>ό<EFBFBD>5ς<35>Gμ?iώ<69>
|
||||||
|
υ<EFBFBD>ρ<EFBFBD>Σ<EFBFBD>Σr<EFBFBD>—ƒ<EFBFBD>ύυΦοpσwζWC£<ή<CEAE>x<EFBFBD>|ΰψ―wW'%όόϋwΑoΗ?=ήΥ_kΑ¬ϊC
ϊ‡ο‡]ιΰ;[ρψ]Ώ<ή<>ήΥϋ$όο><3E>αϋ¶¥<C2B6>rΏ›<CE8F>·<17>άsηρ<CEB7><CF81>αψί.ώΨ<CF8E>ώxη—<CEB7>―‡π?uΌυύί™/·ν³tώΧ°<CEA7>λψ—<CF88>_oώFΗ<46>ίί{}-ύ/}ώϋΝ?ϊωΏ<CF89>όΧ“Ώψ<CE8F>Π<EFBFBD>υ?τ‡ώψ<CF8E>-ΚIώO|Ώ<>ι9<CEB9>κ<EFBFBD>Ώ~*<2A>ό‰Ώ΄ώ<CE84>ΎrύSόό°Zό'Ώ<>ςοος…sϋ―R<E28095>—6ω›κ<E280BA>R—Ώ<E28094>ψ“TώλνηΠ_*<2A>ϊαηπ<CEB7>ΗΧβϋ>wύΕτϋ»γΫ¶¶ώϋϋI]ο·?γρώω<CF8E>ώ£πγρψ<CF81>{θΏmiy0Ύι£<CEB9>ϋε<CF8B>ώνϋΏ4ώωω[aύ[<5B>Ώ<11>Δώ¶n<C2B6>Ηφϋ¨ύΩg<CEA9>kΩ?RόηΫΏ£σ<1F>'<27><>ό?ψ<>όΏήύΏω‡<CF89><1B>ώ?όVύsμΏYωWZφ—]ώΗώ'<27>ψΐ>πΙ<CF80>"<22>ϊsώWϋό<CF8B>φω'ληϋίηΞΏ¶ύΟω?Ξ<>qώ<71>σφςΏΘ<CE8F>·<EFBFBD><C2B7><EFBFBD>ύOό<4F>ψ?ρβ<7F>6υ_kό³]ώχα―<15>ηό§Uϊ<13>ΗώΓ<CF8E>ύ<CF8D>?ξ?qψ…^<5E>γλa<CEBB>‰O<1D>ϋ<EFBFBD>κ<EFBFBD>ΣΦ#5>ΧcUψΦηί<CEB7>ϊ—ϊ<E28094>¥οyωW§<57>;ό<>#Οίγ<CEAF>Χ~—ψfπ_ ~ό?<3F>µώ<C2B5>χ¬?δϊGώω%Υ?Ϊς?…<>ψσΏsώΰ?δςψ2ψΪοΪλ?|oµ?―<><E28095>~ψερ¥οημ<CEB7>ζξ?µν{ϊ-ώΏ<CF8E>ό»ϋόΫ•μ<7F>Φσ<CEA6>½SώΞΡ?R<>ϊύ<><CF8D><1F>?ώό<7F>ψ?€|ΰλΕZσ<5A>®…―<17>±$<24>΅?ϊ<1F>ώμψώ·κ<C2B7>Ζ<EFBFBD>oΥώίχpόΎ‡ώΓ}—ωγρϋ^/…Ώο}ώΟώΗόΧGηίέ<CEAF>ψόF<>ώRψρxς<78>Θ<EFBFBD>«―<C2AB>η£υsο{ΫύτΦΏυψ<CF88>>ρωQύί&<26>¤πσγkϊίΊό—φ<E28094>“κ<E2809C>|<7C>²6ύ]<5D>?ϋΏUιί²ώ―ν9¶ώzϋjΫΏΨδΰ<7F>'ώ|ΰ<03>όί±ψ<C2B1>4ώ΄Vώ<56>υό_β<CEB2><7F>ηό+η<>Ω<EFBFBD>qώ<71>σ<EFBFBD>Μ?φ·σ<C2AD>δ<EFBFBD><CEB4><EFBFBD>‡ύOώόOώωψ<7F>π<EFBFBD>α<EFBFBD>C<EFBFBD>ςω/ψώ‡<CF8E>νρ<CEBD>ΧΧ+ΛΟ:ϊ³Ό<C2B3>τψnΫ|<7C>ζΏϋ½®o[8ώ…§?ώΈώϊ>μ<>ςοίΉπγρΫΒηό<><CF8C>ςσ»QcψeψΫvξtτ'z½Β~E~<7E>“λ?ξ›Γ―<E28095>σsΕΟφ_I}<7D>ΒΛΑ/Οn^ZαCmϊοϋ\ψ1<CF88>°<EFBFBD>W<<3C>Ϊς_<CF82><5F>-ΛNα^<5E>υσσΡ7ώΜ_ΟΗ<CE9F>όΧό·n<C2B7>Ώ<EFBFBD>^¥~υeϊ<65>ν«<CEBD>όΏ»<CE8F>_<EFBFBD><5F>c~(α—<CEB1>¥ϋ<C2A5>οΏβϊ—<CF8A><E28094>i―<E28095>®xώ;ΝΏuωΗώƒύΏeόkϋ<6B><CF8B>~iΞώCw<43>e}<7D>§έ<C2A7>\<>ƒύ?J<>ςO»<4F>5ς<1F>ώ?όVύΨΦωϊ[¦Ν?Ϋομσ<CEBC>jϋ?ρΘό—W\ΧφΏiγ<69>Ξλ<CE9E>ψ<EFBFBD>4ώ§m<C2A7><6D>γOι~@9<>y=ώS~Χχ<CEA7>οϋHόm–ύΏbόΟ’ύ<E28099>ώ'<27>«'^½msγ<73>+ξ<>-Ε<>±<EFBFBD>lΫΔΏmΓ'<27>Οvόkt<6B>Σ®<CEA3>ϋς<CF8B>^οN[χΖ?ΣγKφ<4B>σ!±o¤ϋΏΥφ<CEA5>+πΏ~όίRώρΛώίύ²ύΧΎKόo=ϊgFό‡ός<7F>WΚ<57>οµ<CEBF>¤ϊG;ώ<><CF8E>ΏEώ¥ηλ<CEB7>όΗλνβ<7F>Ηυ£_ΘίOΨ?δθOτzΉΟαο^υJίγΓοσχ›?<1E>υ•~.πΫψKχ?Rόkϋ<6B>ώW<CF8E><57>ƒίΎ<CEAF>ƒώΠ_›ώ<E280BA>ύο<><CEBF><EFBFBD>υΏn<CE8F>ΗΊ<CE97>mώΊύ<CE8A>ΰψώ·‰?ϋ<>ώ
<0A>{ί{ο'…/ύ=ϋΏV<CE8F>³”ώ«Ϊ<C2AB>ΟGΫz’Ζ?΄ΧYώ<59>φnο<6E>Ό¶ώ―γ?cύλχF<7F>#<23>Χ’<CEA7>2ω;οό<CEBF>U<EFBFBD>ϊί<CF8A>ώ‡ώΠ<1F>?ςΏ<CF82>ώnύΖψεΖ—σ<1F>/ψΤ΄‘<CE84>›ΛΏτΏmνρ£tύΏώσΧαϊo©_U:=zώ}Φωoύσ?γτ<CEB3>!Fα;ό[Ηωq=3έυ·Άόο;Ώ<>yΧΧμΛ_—ΝΏ6<CE8F>IρΣ<CF81>Ώχ_ΏΎώυO¨†ύ―έ<E28095>ηχ{Δώκµ<CEBA>µν ώΪπgΜ?υΏθ<CE8F><05>[®<>a[ώYχ<59>β<EFBFBD>Γ<EFBFBD>‡<EFBFBD>Ο®<CE9F>Ob<4F>Νθ<CE9D>£_<C2A3>ώΗώ§ώ/ώπβ?τ²Φ<C2B2> ϊγ<CF8A>£ώ/ώ?κ<>Ω¬<CEA9>g½ώ―<0C>Ωλ_><3E>ρxκ<78>R<EFBFBD>wζώ‡όϋO‚<4F>ύ<EFBFBD>ύOόϋ<>ψ?ςΏMώΟ<CF8E><CE9F>®<EFBFBD><C2AE><EFBFBD><EFBFBD>ϊ[‰<>c<EFBFBD>Α<EFBFBD>Πί&ύ©<CF8D>GύΗιOύΛχΧ<CF87>χ?<3F>Χ<EFBFBD>[΅ώK <09>–ϊ{r<><72>υ<>¨<EFBFBD>m―ώϊ<>ϊ<EFBFBD>Τ³[<5B>
ϋωΗώΗ¶ό_±ώχυΟχ<C2AD>©ο<C2A9>ζΤ?_Οώ§ώ?υ<>©<EFBFBD>OύKϊ%<25>ί;λ<>—ό_µυ7'<27>ύ<>ώΗ<CF8E><CE97><EFBFBD><1F>?ώ<>wλ<77>ίo~xΉω?λ<>C<EFBFBD>ΈοόοΣγ}ϊ§ΖKα§τ_8όΑό_’Κ—ο‡|ΚΙ<CE9A>³ό”βΘηίοό:ώερΫvΎ><19>1ψ―ΟωωσνθύΧ<CF8D>ώ^²όΉχ―ν~wΗ_*<2A>ηΝΟού35Ϋv<1E>ΊξΦχLώOΓ―αS<1B>Ίξ??ό<0F>[ζπ·m<C2B7><6D>Δ|<7C>έοwϋψΓ<CF88>ϋ4α<34>Π<EFBFBD>“ΖΛόιψƒϋΎ><3E>ΪφΏ,ώ3£ών*ρ<>Ψί<CEA8>–§ροΏΫΗΗΏ<CE97>ύ^iύ·γοϋέ¥λ?Ύί8όόx<CF8C>ϊύ
ύf?Ο»<CE9F>ί<EFBFBD>όχγWστ»όυυΏ΄ώƒυύ<CF85>6ύGζΏ}|}ώµΧί:φ7φ<37>Eϋ<0F>?ρ ύ¥ψ·Π―ώ<ϊƒ?ψ[ΑίΧeεΟ©Ώz|¥<1C>9ΧKIΥΞγ_Τ|>ύΏ<0F>~η<>/ώwασΗύ§ZβW-περ/)ύeλΫ¤σίχΌηίΟ[cτΧα©ύ?ΓώΥ¬i]ώkχΣ–<CEA3>²ώoιώn^Zϊή―ώλLώGώ!<21>°<EFBFBD>Χ±<CEA7>gΨ<67>#φ<>ύρ—<CF81>ϋϋώ‡<CF8E>uωί.ώθόψ<7F>Π<EFBFBD>¶υ?ό<0F>Γ<EFBFBD>vψίzώ#γ9<CEB3>Οω<CE9F>ρόIιϊΣΞ<CEA3>$<24>ϊkΒΏγω—™ηΦ9<CEA6>gσό«O―°?{z<7A>§Ώ4<CE8F>ΏύόmΤs<CEA4>ό<EFBFBD>Yηί<CEB7>ί·<CEAF><C2B7>[γόη<>8<EFBFBD>Οώ‡ύ―ρ<C2AD><CF81>΅ώη―Ρ<CEA1><7F>Gώγ<CF8E>Α<EFBFBD>ύmω<6D>°<EFBFBD>ΰθOύκ<>Y―<59>4―ώH<CF8E><48>σ<EFBFBD>λ&ώ+Υ<>“ΕΖβλΤJγ_σΏΟ«<CE9F>£γ<C2A3>—ΖΟζΩ<CEB6>:ρ?β<>θκ?S<><53>ψ?φ<>Eϋ<45>ψ7ς<37>ό?»ρ―‘ύίρ»Ήυ_uϊ<75>P<EFBFBD><50>ϊ<EFBFBD>δ<EFBFBD><11>Η<EFBFBD>«γ<C2AB>[§ώΏT<CE8F>Hγ?δ<>“<EFBFBD>―›<E28095>/³<>Ζς<CE96>Χ©<CEA7><C2A9><EFBFBD><EFBFBD>ώ<EFBFBD>Φβ<CEA6>―'zΡΓΗ<CE93>xΎτuΗ?―<>ΉoΣΧkχ<6B>ΗKαΧξίϋ|ΰώ<>‹<EFBFBD>«IX<49>¤ό9|Iρ?ΏBx5όkγλ―2Ύύπ{ού΅Ώύµλήιϊ_―ώuώΥΉΦΥόuκΏΑ<CE8F>π?όoλφ<CEBB>α‹ωϋ ύ—9ψΞΏυς'χΗ?1ώΗυ3ύ_Ώ<5F><0B><>ϊϋτί¶s<C2B6>›<EFBFBD>Ύ<EFBFBD>ϋάHι―m<E28095>·ΰ_[Ήy‰νχ}8<><38>λ_»<5F>Ν
|
||||||
|
λ_‚<EFBFBD>ωwηώ?θδΏtύ‡}ΣfΘί³όOΛeφθτ?τ·Kό<7F>Δ<CE94>φΧΉNό<4E>Cν<43>‘ψOάΏdόόε<CF8C>όν_¶gdύ_¤ς<C2A4><CF82>ρΏ>ϊΤχ<CEA4>½σ/~~Νυ§-ίΗό<CE97>.<2E>8¶οsγΛώ=ψΘ<CF88>‘ύ_Έ<5F>‘ΞΏ®όΩ<>…λ―eώΚϋΏ»ρί<<3C>7ρOβ<4F>Ψ<EFBFBD>wΛi―<69>Ϊ–<CEAA>£i<C2A3>θ>Ώφό“<CF8C>GώόOώ<4F>UωgέΏ‹<CE8F><0F>ώ?Λώ?™ύ7#<23>_7ώ<0F>c<EFBFBD>c<EFBFBD>k<EFBFBD><6B>Ήϋωπ<07>ΟΒ<CE9F>½ϊ_[ώKυ~ψ]}<7D>ύ΅Ώύ¥υΏ¶νόύσ‘®/υ|¤λYqώe¬ώΥ<ω/…/{¦Θi:Kλ<4B>ω<<3C>‚Χ<E2809A>i|ιο|ώ«Δ<C2AB>-λου<CEBF>β<EFBFBD>ηγΜ<CEB3>Ϊλ_›<5F>?Gώ<47>Χ<EFBFBD>{>ζΞj~ύωOΧΏ³)<29>°<EFBFBD>ΥγΟ<CEB3>Ώmόϋ<>sφ<CF86>ώiWτ_{ηϊ·®<C2B7>΄ιg}ύέGώΟ‹<CE9F>kΗ‘<7F>Π-ψΨΨψ<7F>΅<EFBFBD>ϋύ_τΏ΄έ<CE84>‘ώ―Χ?ύθ<7F>C<EFBFBD>«ύ<CF8D>θYύΧyύµεΏυώΏΨΘ?{ςω?«<>υ<EFBFBD>ύΏΞϊ—φί•<CEAF><E280A2>>ύΣϋ?©ώΧ±<CEA7>Ρ<EFBFBD>Ίό<CE8A>9ςO<CF82><4F>uφ<75>Φεϊ_Χ<5F>WΞ“Ώ3σ<33>Ϋυ<CEAB>Τ<EFBFBD>ƒώG<CF8E>γ<EFBFBD>Η<EFBFBD><CE97><EFBFBD><1F>?ώππΏιω§yς_G<5F>[—<>Πύ?Η<>ΣΎ]Ι<>gέ<67>…ύ<0F>Γ<EFBFBD>ψΏΑ<CE8F>όοV<CEBF>γΎ‡ώΗΦρΉψ—&όϊ<CF8A>xς<78>π<EFBFBD>χΖΏsώόΪψ\ό<CF8C>υOό_φYJΏΩΟσξη·#<23>έz<CEAD>©<EFBFBD>Ϋε――<E28095>·ύωsυη8<CEB7>΅G<CE85>‘ωo_<>νυ·<CF85>ύ<EFBFBD>ύgΡώΓ<CF8E><CE93><EFBFBD><EFBFBD>ψ/ψƒΏυψΏ4ώ3ζ_^GώΫΜ<CEAB>%ώΗώ<CE97>σ―ΔΨ<7F>qώ<71>σ<EFBFBD>Θ?μ«ψ“<CF88>Cώφ?ωπ?ωδ<7F>α<EFBFBD>Γ<EFBFBD>‡<EFBFBD>ύoηόό<0F>Γ<EFBFBD>¶ψ<C2B6>υD/zψψΟΗu®<75>―;ωωϊ<CF89>ϋ6}½v<C2BD>xΌ~νώ½ΟχΩψΏz‘„ύOz>KΧ—τώ<CF84>ηο‡Ο_νU»?τΏύηΒΧ”οςόoyώσΧΧ+<2B>Ω<1F>{~<7E>ώ<EFBFBD>ΰΧkγ<6B>λgόeω―RωΏR<CE8F>'ΧΏ>ί<>*ώύόωw<7F>=‡―<E280A1><EFBFBD>?Sλ―6ήΏσΏώϊ—ζΘς΄υ<CE84><14>γώαόσά:<3A>ΟΗάω«jQώa<CF8E>³Ώµ~½ί~
_<>υUΫ/υοΏΚΟΫΏ?ϋάύ<CEAC>v<EFBFBD>aύύ<CF8D>uϋ_—~ΦΧί=ε?ώ?όψ<7F>>Α<>‡ύ<07>CΛφΏΎ<CE8F>QΎuϋolώηω?οΉώηϊ<CF8A>ύ;ώ<19>ώΌψ<CE8C>4ώ§m<6D>αΞΏ‹#9?~,<2C>Kρ<4B>µό<C2B5>}ρ³ωϋ<CF89>χΖ<CF87><CE96><EFBFBD>£<EFBFBD>-ΗZβί±Ό<C2B1>ε™tώµεΏυψ?φ<>]ϋ<>ψ7ς<37>ό?»ρ/ΙώΗι‰ό;φ'ΫΦn<CEA6>§β<C2A7>¥ρΑυθ<CF85>#ϊξώoµύ<C2B5>;ω<><CF89>ωΟΦσ<CEA6><CF83><EFBFBD>’<7F>WΣ<57>§Ώ<C2A7>ρ?Ν‹<CE9D><E280B9><EFBFBD>Oώ<4F>jω<6A>=φί<CF86>όΝψ/ώ<>ώ™<17>Χ±<CEA7>‰<EFBFBD>γ<>:’ρϋWζ•ϋ]m|ν{ΰψο‡<CEBF>φ?<9ωϋ®†_ΓΏm<CE8F>]φhΒ‡ώΠ_›ώηϊΣqύjχ<6A>±ϊΧωϊΣwΗ<77>ξσ<CEBE>ήΔϋ7η?<3F>χsπΟΓ―γί²<CEAF>,νΰψί:<3A>ΫΕ<CEAB>ύGΎυwλϋ?η_,_—Ξσ<CE9E>φ+~Ϊσ7cώΣςΧΙΩψϊσ1oόΊϊ_φόw™τ?ςEω<45>.ωΛώύo]<5D>Cθ<7F><CEB8>ί²ό·}ώόΗω<CE97>jώώυπ5σ<35>βΌΉ9η/ΞωιΌΌtώ<74><CF8E>W-ώΥ–<CEA5>ΧΏ'ώ6#ώ¥{ώ'5<>νω—)όΣωξy9<79>SΧ΅ύΊο²ύuνώΟΗ\ψϋ>k<>oAώ<41>ΦυσY^Iθ―-<2D>kψΦΦ_n^ZηsΕυ―}]›<>ξ>Θ?ΰ_wώw^<5E><>{<7B>ώ¤σΏϋ<C2AD>τ~eΞϊί¥ν<C2A5>Τψ’ύ†<7F>;ί4f<34>—νψ_›<5F>ΗχίW¬νύΏ5ωGύOόψ<7F>π<EFBFBD>Ω<CEA9>3n<33>ΝXΪφό<>ύoΫώW_ΐ>πo(<28>ί<07>:ωΏ|θύ5θ~<7E>ϋyηυ8>•»β?o|ψ~<7E>+qσοjeωχΏjώϋα—Ηϋίo›n&K<>ΞχΉσοΧFΑ?_ϋώΌΘαW[γs<CEB3>ΧX<CEA7>Ϊό?ωwχω·.<2E>μΪ<CEBC>Ίρ?ύψ·uό±<CF8C>mΫ<6D>ϋΚO·~όϊ°γςΧΏ<CEA7>οwx<77>uΦΏ]ύ7‡ώRω7oύΕγΫπG<CF80>ιΔ<CEB9>µγΏΘλτ―<>ήF<CEAE>0ώχΐώΓώΓ<CF8E>ύυθΏbύ©{ΤΏ<CEA4>®Ώy|λσoiύKύΗ<CF8D>wέϊΟrό¤ώνw‰<77>a^ύρ4όψ/~ώkύ<6B>οYΘ?τΟjυ<6A>ϋε—T<E28094>hΛ<68>ώγΟ<CEB3>Ξωƒ<CF89><C692>Θ?ΰΛΰkΏk―<6B>π½ΥώΌjώϋα—Η—Ύ<E28094>³<EFBFBD>›»<E280BA>Τ¶<CEA4>νι<CEBD>µψ<C2B5>~ςοξσoWώ±<CF8E>[Ο<>χNω;G<>Hύ?θτ?ώό<7F>ψ<EFBFBD>ρ<EFBFBD>Σ<EFBFBD>ψΐ>ύίι<CEAF>ύ΅?ύΏι<CE8F>ύήψ[ώιόuνoψώ·Ν<C2B7>τ<EFBFBD>µ½<C2B5>Ψχp|νsο{ού¤π¥Ώ?ώ<>—ϋ<6<>ξώµϋΝ<CF8B><1F>§<EFBFBD>/ύ_Kύη]Ώ cύ„ρƒ}—Εβρuώηϊ—ΔOζΜΏvό'G<>CΧGυ^ώ¥<CF8E>Ώ~Z<>ΗγkϊίΊόο<>'Υ<>µώe5}~u<>?«ύ<C2AB>µιΏmmλ<6D>κώ—cλ―½<E28095>΅¶ύ‹ύ‡ύ‡<CF8D><E280A1>ψύ<17>|«ύ?ι<>C<EFBFBD>ϊ<>Xν<58>C<EFBFBD>kΫςΏήΏΎό.<2E>mώ“β§=πςωό»φ<C2BB>»3ώ<33>Ψϋ<>ώ<EFBFBD>πΏ]ώ·†?ϊ<1F>ώ?τ?ϊώ‡<CF8E>αKόo=<3D>ό9<CF8C>Βω<CE92>}/ηOί<>ζ•σΏυσ?Ι<>µM<C2B5>}<7D>?¦<>Ύ‡πέύΧ8<CEA7>²ήω<CEAE>wζ?sώ7Χ<37>2<”<>_6#<23>ΏΤ<CE8F>®~ώGή<47>ΞzώΏζω³uΟ<75>[:<3A>ΗωΞ<7F>³<EFBFBD>ηό?ηlΦ<6C>?<3F>έ&έύ}›k<E280BA>ύφ?η<>9<EFBFBD><39><EFBFBD><0F>ώ?{ώ?μ?ΞC›τ§ώώ<>κ<>¬ζ³ς.<2E><>Hγ+Ψ<CEA8>ώO<CF8E>σw«Τ<C2AB>ΛΗΟ<CE97>λ£υΏkϋ<6B>υβVμτ?ω_Τ<5F>³<1B>Ηώ³m<C2B3><11>Fώ“<CF8E>g7ώ%ν_:g<>Ή^<5E>κ<>S<EFBFBD><53>ϊ<EFBFBD>Δ<EFBFBD>-Δ<>Wτ<57>½³ώΏD<CE8F>Μ9<CE9C>Jώ?ω<><CF89>φο<CF86>ώυ£ϊG;ώ‹<CF8E><E280B9>ώ<EFBFBD>vσ?BϊΟ—£<E28094>yώΟxΖί|\—$]<5D>ε\?ε]π―~~mψΠϊλΚ<CEBB>σϋοχ;―ί<1D>{ΟΏτOΞ<4F>µϋ_ϋόπ?όo™<6F>Αί¦ύοϊΣrψΠ_·ώ«¶ώΥ―?Ί
|
||||||
|
<EFBFBD>…ο9ωι<EFBFBD>.„_οΏ’ό<E28099>‡<EFBFBD>έηύ<>όΧ¨<CEA7>+ο<C2AD>Π<EFBFBD>θθo—ώψ<CF8E>ρ<EFBFBD>Ήσ<CE89>ΗωΔάωΟ1ψρxw>+=^
|
||||||
|
?•<>ώΔΏ_Z<5F>α^±τΉ7>γ<>εΆλ3-?έοΫΧi|›ό—Ζ<E28094>¤ς_o<5F>;‡ώ2ω·mmπ[β-Ο{ώύΌυ—²™έύόσϊ<CF83><CF8A>ς_V<5F>΅Νώtχ?ΣΏ<CEA3><CE8F>=Ώ'<27><1B>OL<4F><4C>ϊΫ<>•θ―-<2D>Ηρoί<6F>ωψΗό―½ώΗί<CE97>b<7F>b<EFBFBD>—νσϋKj<4B>λο<CEBB>¥ψKχ<4B>σζ?=Ώδ<CE8F>‘<EFBFBD><07>“<EFBFBD>ΧO<CEA7>O—ψΏρ<CE8F>α<EFBFBD>Γ<EFBFBD>gΡ<67>7Οώ“<CF8E>?Ρ<><CEA1>ΪεμΞ<7F>0<EFBFBD>ρ<EFBFBD>ηό?ω_<CF89><5F>‡ώσΏuΞ<75>¬<13>²ι<C2B2>ΛΡΏ΄WNύN<CF8D>¬c<C2AC>“<EFBFBD>Οω?Ξ<>qώ<71>ψ?ω<>–σ<E28093>±<EFBFBD>‰<EFBFBD><13>'ώOόί¶ώ«Ε?GδW[όW;ώΟωO«τ'ώ<>ύ‡<CF8D>ϊ[υ<>kχ<6B>Ρ„<E2809E>wίΕ0γλ<CEB3>5ήϊό[_<>R<EFBFBD>³GςϋΡ8Ί„ΧγοΛς«NΏ«ύ<C2AB>9<fϊ<66><CF8A>~κσW›gωό<CF89>ω¤όΧ~<7E>τίµώ›λΧςύ―MIόY:<3A>λΘώcπςωΗxνυ―c®³ώ¥RϊιόΝΫ<CE9D>IυΏ<CF85>ύ<EFBFBD>ώΧε<CEA7>Ο‘w<7F>›ςύ―λ<E28095>Σ–Ώστ<CF83>Τ<EFBFBD>ƒώG<CF8E>γ<EFBFBD>Η<EFBFBD><CE97><EFBFBD><1F>?ώ/ΰψοΤ<CEBF>:ρ<>μ/μ?θ<><CEB8>Ο¦<CE9F>ίΊ<CEAF>O{<7B>?o<>uEύ ψώ<>|ώΫφ<CEAB>Ύ‡γ<E280A1>ο^<5E>γλ!όάσ—Ζο{yΌ~<ώο§<>‡<>1ΗυΡωwχ?><3E>ƒ‘§Ώ~<~Δώφω)ΌΪ<>-τ―Ν<E28095><CE9D>φΏτωί9<39>ρ<EFBFBD>_Ϊ>χΎ·έOoύ<6F>β5—~zο9ϊό~<7E>ΟΣ<CE9F>θ<EFBFBD>6ω'…<>_Σ<5F>Φε®<7F>_8<5F>γς«¦<C2AB>sύΟZυ~|›όµΎ<C2B5>[•ώ-λF<7F>»}<7D>»ώ<C2BB><CF8E>ςόΉϋa<C2AD>b<EFBFBD>Ω¶<CEA9>π<EFBFBD>γ<EFBFBD>>π<>ΟωkωΏΦσ<CEA6><CF83><EFBFBD>΅<EFBFBD>µνΟΗ[Ο<>b<EFBFBD>gg<67><07>1<EFBFBD>ΨίΦα“<CEB1>Cώφ?ωπ?ωδ<7F>α<EFBFBD>Γ<EFBFBD>‡<EFBFBD>ύΟωψώ‡<CF8E>?—<>ΏΎ^ωX~ώΣΡ<CEA3>ευ¤ΗwΫζϋ7<CF8B>έοu}ΫΒρ/<ύρΗυ£?‰λ<E280B0>ςϊύ\ψρxwύ¨ΟΰΟ?ψ?εηw£ΖπώΚπ<CE9A>~G®±λOtτCrύ<72>Β>Η3ΦΨ7ωΏ¶ώΟΟ?Ψ9υ}
|
||||||
|
/Ώ<<3C>Ήyi…ύµιΏοsαΗpάύSσ©-<2D>εωί²όηώαυX??}γΟόυ|ΜΙ<CE99>ΑϊύίΟλ?΄§Στχα•ιs¶―Jσ_κΏΧ‚Ί<7F><CE8A>γΏη£Ξ<C2A3>1?”πKι<4B><CEB9>ύΞχ_qύKΟΟ΄<CE9F>ΧΦW<<3C><>ζίΊόc<CF8C>Αώί2ώµύOiΏ4g<34>΅»<CE85>²Ύ<C2B2>ΛΫ<CE9B>ηώΓcςΧί<CEA7>Δύ<CE94>WΨ<57>`<60><><EFBFBD>†ό+<2B><>[}η‘<7F>ψ<EFBFBD>π<EFBFBD>α<EFBFBD>³κ<C2B3>Γώ³Ξ<C2B3>Πί2ύkώΩ~<7E>c<EFBFBD><63>WΫ<57>‰<EFBFBD>CζΏΌβΊ¶<CE8A>M<1B>w^—Ζ¤ρ?mϋοJε£εύηυψOω]ί<>Ώο#ρ·Yφ<59><CF86>ρ?Kφ?ϊ<>ό―<CF8C>xυ¶Ν<C2B6><CE9D>―Έ<E28095>·<14>Ηώ³m<C2B3><11>¶
<0A>ό?Ϋρ―ΡύO»ώοΛz½;mέ<1B>L<EFBFBD>/Ω<>Ο‡ΔΎ‘ξ<E28098>VΫ<56>―ΐ<E28095>ϊρKωΔ<7F>-ϋWτ<57>Ιφ_ϋ.ρΏυθ<CF85>ρς<>Ι<EFBFBD>_)<29>ΏΧώ“κνψ+ώ<>ω—<CF89>―+ς―·<E28095>‰<EFBFBD>Χ<>~!?a<><61>£?Ρλε>‡Ώ{Υ(}<>ΏΟίoόxόΧWϊΉΐόmγ/έ<>Hρ―νjψ_}ώg~ϋώϊCmϊkφ?Ό;ώ3Φ<33>Ίύλώ·9ψλφ<CEBB>ƒ<EFBFBD>αψί&ώμNψ7|ξ}ο½<CEBF>Ύτχμ<CF87>ZύΟRϊ―j<E28095>?mλI<1A>Π^<5E>eω?ΪΈ½<CE88>σΪϊΏ<CF8A><CE8F><EFBFBD>υ―ί<E28095>ύ<>ό_KώΛδοΌσVύθ;ϊϊCό<7F>Θ<EFBFBD>vϊ»υγ—_Ξώ½ΰS<CEB0>ΡFώo.<2E><><EFBFBD>ύ¶µΗ<C2B5><CE97>υ<EFBFBD>ϊΟ_‡λΏ¥~UιόυθωχYηΏυΟ<CF85><CE9F>Σ†ό…οπoδ<7F>ΕυΜtΧί<CEA7>ςΏοόώη]·^<5E>±/]6<>Ϊό'ΕO{ώήύϊϊΤ?΅ώφΏv<CE8F><76>ίοϋ«ΧώΧ¶$ψkΓ<6B>1<EFBFBD>Τ<EFBFBD>Ά<EFBFBD>όoΉώ‡mωgέ<67>‹<EFBFBD><0F>ώ?»ώ?‰ύ7£<37><C2A3>~ύ_ψϋ<>ϊΏψΐό‰<CF8C>Π<EFBFBD>ΙZ<CE99>'θ<><CEB8><EFBFBD>ϊΏψ<CE8F>¨<EFBFBD>g³ώ<C2B3>υϊΏ2όg―ωόΗγ©<CEB3>Kύί™ϋςο? >φ?φ?ρμβ<7F>Θ<EFBFBD>6ω?7ώ»bώ7ώ?θo%ώ<>ύ<07>C›τ§ώυW¤?υ/ί_<CEAF>oά<6F><^<5E>o…ϊ/%ό[κοΙύ<CE99>kΤ<6B>£ώ·½ϊ?θκ?R<>Νnύ7μ?δϋΫςΕϊίkΤ?·ή<C2B7>§Ύ<C2A7>›S<E280BA>|=ϋ<>ϊ<EFBFBD>Τ<EFBFBD>§ώ?υ<>-ι<>•όο¬<CEBF>_ςΥΦί<CEA6>ότ?ϊ<1F>?ώό<7F>ψ<EFBFBD>ί<CEAF>Ώύω=ΰεζ<CEB5>¬?ύγΎσΏO<CE8F>χι<CF87>/…<><E280A6>αππI*_Ύς)'<27>ΟςS<CF82><53>!<21>ΏSπλψ—ΗoΫωzψόeόΗΰΏ>ηηΟ·<CE9F>΅?τ_Cώω{ΙςηήΏ¶ϋέ©ό<C2A9>7<EFBFBD>=ΏχΟΤlΫy|κΊ[ί3ω?
Ώ†Om|κΊ<CEBA>όπ?όo™<6F>Αί¶ύ?<12>ρύwΏίνγ<0F>sμ<73>Ρ„?B<>O/σ<>¥γξϋϊόkΫ<6B>²ψΟ<CF88>ϊ·«ΔbZ<7F>ΖΏ<CE96>ύn<1F>ώχ{¥υί<CF85>Ώοw—®<E28094>ψ~γπσγύλ3τ<33>5τ›ύ<ο~~;ςί<CF82>_ΝΣ<CE9D>νςΧΧ<CEA7><CEA7>ϊΦχΪτ™<>φρυωΧ^λΨίΨν?ό<>Δ$τ—βίBΏ^ψσθώΰo_—•?§ώκρ•r|ζ\/%U<>9<EFBFBD>i|Pσωτ<CF89>>όSψ<53>+Ύψί…Οχ<>j‰_µΐ—ΗΏ¤τ—<E28094>m“Ξίσ<CEAF>?oύ<6F>Ρ_‡<5F>¥φ<C2A5>ϋW³ώ¥uω―έ<E28095>M[ώΛϊΏ¥ϋΈyiι?xΏϊ―3ωω‡όΓώ_Ηώ<CE97>a<61>Ψ<EFBFBD>χΗ_JμμψώΧε»ψ£<CF88>ρ<EFBFBD>α<EFBFBD>C<EFBFBD>ΫΦ<CEAB>π?ό<0F>Ϋαλω<CEBB><CF89>ηό?η<>Ησ'¥λO;<3B>“ό/θ― <09><>η_f<5F><66>Yηό<CEB7>Νσ―>½ΒώμιύA<CF8D>ώ<EFBFBD>ό<EFBFBD>φσ<CF86>µύQΟuς<75>g<EFBFBD>Kίrώo<CF8E>σ/<2F><>γό?ϋφΏ¶Ζsώ‡ϊ?<3F>ΏF<CE8F>qώω<><CF89><07>τ·ε<C2B7>Γώƒ<CF8E>΅?υ_¨<5F>g½ώΣΌϊ#=ώΟ;®<>™ψ―T<E28095>O<16>‹<>S<C2AD>)<29>Ν<7F>>―ώ<E28095><CF8E><EFBFBD>_?›gκΔ<CEBA><CE94><EFBFBD>£<EFBFBD>©<EFBFBD>Lύ?β<>Ψν?βίΘς<7F>μΖΏFφΗοζΦΥι<CEA5>Cύκ<7F>“<EFBFBD>Gό<1F>―<EFBFBD><E28095>o<EFBFBD>ϊ<EFBFBD>Rύ#<23><><EFBFBD><EFBFBD>OώΏnώΏΜώΛ<>_§ώ?ώϊZ‹<5A>Ώ<EFBFBD>θxjχόp<7F>λ\<5C>μλ<CEBC>ΧΥπ―~~mψΠϊkΡΏΝ~©εO<CEB5><4F>Ώ;ώw<CF8E><77>¶ϊUωϊiσπ―ΑΏξωαψώ·‰Ώuϋ<75>πWύύ„ώ«άxηίzω<13>λµρΗυΥΰC<CEB0>ΈoΝΎ—4dκw<CEBA>ωΧΤΏ-ψΧΦ_n^RpRίkσίΉ<CEAF>Μσ‘“<E28098>cύoςύgVX<56>όο><3E>θδΏ¦όΧ–Ώμ<CE8F>Π<EFBFBD>Φυ?τ·Kό<7F>Δ^ΉaώΓ‘<CE93><E28098>Ύ>ϋώρx)όΪύΑϋ—λισ“µώ'©ώ9γωOi‰θϊ£΄¬<CE84>Ϊψ²ώ—Ε<E28094>δφΗ
|
||||||
|
ώ<EFBFBD>qϊKε<EFBFBD>v<EFBFBD>§τz‘®ΏήϋλΙ<EFBFBD>#3΄σπΗμOw<4F>3ύSφ―ώό<7F>¥ύ<CF8D>Ώ^Z―cϋΏ<ύυε<1D>Ϊϊ«ο<C2AB>όόοσ|j®λρ7β<37>ΨΗΨ<CE97>zύ<7A>υνώσμ_Νώ―δ<E28095>ΩΞ<CEA9>³Ξ<C2B3>Φσ<CEA6>μΚ?λώ_όψ<7F>π<EFBFBD>Yφ<59>Ιμ§ϊS7ώ<0F>c<EFBFBD>sώη®ηOΟxΖλΙ<CEBB>χΑΏϊωµαCθ―A<E28095><41>Τ½<CEA4>ήsυ•βϊ_ξ|IyΌ<79>}\u<7F>σ/ωϊPmΧ¥τ“Β»<>£Θy:Ο<><CE9F>Ϊ_
ΏΡΏσϊ{½§ωΏeύ¥Η»ψΘ<7F>Ϊλ_›<5F>?Gώέ}ώmΚ?μΝψίρoλψc<CF88>Ϋή<CEAB>IκΏ¶ΧWΥgΥ]<5D>–υίϊKείΌυ7―ώ―=ύχήψΏvόωύϋπ΅<~ώ?φφώθ―ι<E28095>ϊϋ)χ―r<E28095>λYλ?¦ Ώ¥Eδ<7F>Η[<5B>λλ_κnι<6E>Sλ?“—_uϊ]ν<>Οα1Σ<31>χ<>Ιυιkν<6B>36<33>cώ)<29>µίΏ½<CE8F>Ο<<3C>Νυλω‡ώΧ¦Ώ$ώ,<2C><>uδ
|
||||||
|
<EFBFBD>ϊϊ›'<27>α?δς<>ρZλ_Ηώ\gύK<CF8D>¤τΣω›·<E280BA>“κϋύ―Λ<E28095><CE9B>#<23>ξ><3E>6εϊ_Χ<5F>§-ηι©<>ύ<>ώΗ<CF8E><CE97><EFBFBD><1F>?ώό_ΐ>πί©<CEAF>uβ?+Ψ_ΨΠ<1F><>M<EFBFBD>Ώu<CE8F><75>φώήώλ<CF8E>ϊπ?ό<>ωόώ¶ν<C2B6>}Ηί½>ΗΧCψΉη/<2F>ίχςx)όxόίOy|<0E>cώ<63>λ£σοξοχ\ΚΣ_
|
||||||
|
??bϋό^ν<>ϊΧζEϋ_ϊόο<CF8C>?ιxΗ/m<>{ίΫξ§·ώGρ<47>K?½χ}~ΏΟηιGτ›ό“ΒΟ<CE92>―ιλς?μζλΟΤυ~ωUΣ<55>±όμΥ<CEBC>ωρmςΧϊώoUϊ·¬<C2B7>Τό§ΞΏ—ζίη®Ώη£<ξ~kΨΏΨ¶ν?ό<>ψ<EFBFBD>€|ΰsώίZώ―υό?βθmϋsΕρΦσΏΨ<CE8F>ΩΩ<CEA9>ΑΜ?φ·uψδ<CF88><CEB4><EFBFBD>‡ύOώόOώωψ<7F>π<EFBFBD>α<EFBFBD>C<EFBFBD>sώώ‡<CF8E>α<EFBFBD>Οε<CE9F>――W>–<><E28093>tτgy=ιρέ¶ωώΝχ{]ί¶pόOόqύθOβϊΏΌ~?~<ή]?κ3ψσώΟGωωέ¨1ό<31>Ώ2ό£ί‘λ_μϊύ<>\ΏΆ°Ορ<CE9F>υφM>Γ―<E28095>σsΕΟφ_N}<7D>ΒΛΑ/Οn^ZαCmϊοϋ\ψ1w<>Τ|jΛyώ·,<2C>9…x=ΦΟΟGίψ3=sς_gπ<67>~<7E>χσϊνι4ύ}xeϊ<65>ν«<CEBD>ό—ϊοµΰ<C2B5>ξ<EFBFBD>ηψοω¨σΜ%όRϊ£tΏσύW\<5C><>σ3νγµυίΟ§ω·.<2E>Ψ°<7F>·<EFBFBD>m<7F>SΪ/ΝΩθξΏ¬ο<C2AC>ςφ<CF82>Ή<EFBFBD>π<EFBFBD>όυχ?q<>ηφ?Ψ<>£τ<C2A3>!<21>JηΗΦ_ίω_δ?ώ?όψ<7F>¬ϊ<C2AC>°<EFBFBD>¬σ?τ·L<C2B7><4C>¶ί<C2B6>Ψη<CEA8>Υφβ<7F><CEB2>ω/―Έ®νΣΖ<CEA3><CE96>Χ¥ρiόOΫώ;Η<>Rωhy<68>y=ώS~Χχ<CEA7>οϋHόm–ύΏbόΟ’ύ<E28099>ώ'<27>«'^½msγ<73>+ξ<>-Ε<>±<EFBFBD>lΫΔΏmΓ'<27>Οvόkt<6B>Σ®<CEA3>ϋς<CF8B>^οN[χΖ?ΣγKφ<4B>σ!±o¤ϋΏΥφ<CEA5>+πΏ~όίRώρΛώίύ²ύΧΎKόo=ϊgFό‡ός<7F>WΚ<57>οµ<CEBF>¤ϊG;ώ<><CF8E>ΏEώ¥ηλ<CEB7>όΗλνβ<7F>Ηu^ΌxΩ}Ες%–µλWΓΏϊωµαCθ―ωςk+¥Ύ<C2A5><CE8E>®$wόο><3E>~}/}ζό±<>@<40>ώΥΟ<0F>Γ<EFBFBD>¶ωί6ώΦ_G½ΐψ½υχµογλ«Α·ώ’ϊ<E28099>¤σ―kψΧΦ<CEA7>Τ<EFBFBD>¦½ώµλ<C2B5>®°ώ%ψί}ώΡ<CF8E>ΘMω―-Ω<7F>΅<EFBFBD>λθo—ώψ<CF8E>‰<EFBFBD>ψω…q~bϊzοόΦξ<1F>—Β―έΏχω>®[½ξz£„υ<E2809E>rω—ηό©–ψ‹?>¬<>—®2“?<3F>™Β―6ΎτrΟ<72>ώΎ%~$yIγWsΖ<73>Σ_*<2A><>σ_‚<5F>ΓΏ4ώΌfΛλEΊώzο―'<27><EFBFBD>@ώλΦ<CEBB>Σ—<CEA3>Τ<EFBFBD>ΠΜ?^aύ[><3E><>}<7D>ύΫW¥σ—cφgΩώΧµdψΟ³ΏηΝκόkm<6B>PΫ<50>δνgωϊίΝxώΪ«†<C2AB>τ<05>kσ<6B>uω£WΓ<57>Ώ<EFBFBD>·%<25>¬ϋρ<7F>α<EFBFBD>Γ<EFBFBD>gΩ<67>'³<>fθOMϋώΗώΗώW_<5F>g<γo(<28>ί<07>κηΧ†ύ΅ΏύΟu®^οΗΉ
|
||||||
|
7ήνύϊR®ΎRyΌ<79>½{>ύϊw1~ρσµ_—<5F>O
|
||||||
|
μz<EFBFBD>ώ!oδι<kώk5όF<CF8C>τλ<CF84>ιΧΤδ<CEA4>Ο‘w<7F>›ςϋ_3ώ·FόΫ:ώΨ<CF8E>¶χ.^βlΒΧϊI_ο•―µϋ―°ώ-λΏ9τ—ΚΏyλ/½Ύjψ£<CF88>ή<1F>Χ<EFBFBD><CEA7>"<22>΅ώ#τ<>ηΟΟ<CE9F>ΗώΓώΓ<CF8E>ύ5ύ_<CF8D>υ§ξ]<5D>κώγΟΏυυ/υ?ϋq¤Ώ<C2A4>σχρυψ{έϊΟuόsxΜτ<CE9C><CF84>ύΤη―6ΟςωσΜ«?^»ϊοZ<CEBF>Νυλω‡ώΧ¦Ώ$ώ,<2C><>uδ
|
||||||
|
<EFBFBD>ϊϊ›'<27>α?δς<>ρZλ_Ηώ\gύK<CF8D>¤τΣω›·<E280BA>“κϋύ―Λ<E28095><CE9B>#<23>ξ><3E>6εϊ_Χ<5F>§-ηι©<>ύ<>ώΗ<CF8E><CE97><EFBFBD><1F>?ώϊρβΕ‹ώοτ<CF84>ώΠ<CF8E>ώίτ<CEAF>ΎΖ<CE8E>#³_εψλΪίπ?όo›<6F>ι<EFBFBD>kωυχγϊ<CEB3>8<EFBFBD>αρwΌάη±ώ“ξώµϋΝ<CF8B><1F>ΟχΏ<CF87>οίφΉχΥ{?)όφίΣ<CEAF>•ώΏΗ<CE8F>Ο?ΗωA<CF89>7γρwΏηΨ*λ_™3<E284A2>ΪωO<CF89>ΎΗόεθ?¦?στLλοvψmγkϊίΊόο<>'Υ<>µώg5ύu<7F>ΏΟί<CE9F>ι<EFBFBD>ΏVΏΎ¶<CE8E>―ξ9¶ώΪϋjΫΏΨ¶ν?ό<>Δθ<7F>Θu®[ξ<>I<EFBFBD>ϊ<>Π<EFBFBD>Ηf<CE97>ϊ_Ϋ–<CEAB>qέϊT<CF8A>ϊm+υΉ—ΞΏ®ό―γ_[ΉyIΑI}<0F>!<21><>\·Ψ<C2B7>οξψN<7F>EμϊΒ<7F>vωί&ώθόψ<7F>Π<EFBFBD>θψώ‡<CF8E>ρΏυόGπηΕω—ί™Ξ<E284A2><CE9E>―χζ/εΧ³vώ'ω_ΠΏ„<CE8F>όήϋk<CF8B>Ρ;<3B>£<EFBFBD><C2A3>lύό―£Ώ<C2A3><CE8F><EFBFBD>λ?Χ<>—<EFBFBD><E28094>(χ―«<E28095><C2AB>‘φΏ#<23>_σόΩ
|
||||||
|
η_8<EFBFBD>ΗωΫ/φ<>Vρηόυ$ηΏΫδo<~¥σΟΤ<CE9F>αόΏuω<75><CF89><0F>ώ?‹ώ?μ?ψϊΫ¥?υ<>lΫΪυGΦX<CEA6>zψ―T<E28095>o$ώ#<23><>P<C2AD>I<EFBFBD><49>iΖω?]<5D>Hίtό,Όή_<CEAE>»΄<C2BB>Χ<EFBFBD><CEA7>Y·<59>Ρ<EFBFBD>¶_Τ<5F>³<1D>Ηώ³m<C2B3>ρBώ“<CF8E>g7ώUΫ<55>ΔφσXώ_iώυϋΏR<CE8F><52>ϊ<EFBFBD>Τ<EFBFBD>'ώoΡ<6F>«ν<C2AB>Σ®<CEA3>/Υ?ςσ―δ<E28095>“<EFBFBD>―<EFBFBD><E28095>?n<>IυΟ
|
||||||
|
υ<EFBFBD>ρ<EFBFBD>Σ<EFBFBD>Σnώ―T<EFBFBD>σ[’ξώ―ωwς/ΝRψ)ωοΓ<CEBF>ωόΑό]ύβγ»m+Αύ~>ώπsψ<73>Η‡υ—ΓZ0γψηα»y9γό67<36>ΠϊλΠ<CEBB>Έ―ϋϋGC<43>BψΟGί}οθ<1F>?Ύχο<CF87>9ψKΧ<4B>Όω<CE8C>ΗϋΧ<CF8B>οάΎ!<21><>¶•αΟε<CE9F>~ψ5όύϊjρσΖχ†<CF87>αψί2ώΨ<CF8E>ρψΏ<CF88>Τυ~ΞVοβeόGαΗγ<CE97><CEB3>ςxθ<78>ΦΟGiώs<CF8E>¥τ_Ηώ/γ<>ώ΄<‹ρΟΟ<CE9F>Ξϊ?ΛΟάυ<CEAC>ΎρχiϊηοΏ<CEBF>ώοΓ_ΊώηΝ<CEB7>ΎΟ΅ϊω―)<29>Gεo<CEB5>_ςΟΟώύ<>ώ‡ώΠ<1F>?ςΏίηίmk<1F>£?πο<05>ψ<EFBFBD>'βίρΏmνϋΗ<CF8B><CE97>ΏWώ–Χ~|Nώ<4E>ΖΏζΚ<CEB6>ϋΔ<CF8B><CE94>τ—Κ<E28094>~ψ!ύλγγυΊm+Ώυδ«ύώ©γρ<CEB3>΄ν_ζΞΏ6<CE8F>µβ?ΎΎvώ®<1F>®ψρOβ<4F>Ψ<EFBFBD>λεΏ΄Ϊ_cφΏ–ύ#Ε_ΎtώΙ<CF8E>#<23>ώ'<27>Ο<EFBFBD>ό³ξ<C2B3>Ε<EFBFBD>‡<EFBFBD><0F><>]<5D><>Τώ›•<E280BA>―<15>…<EFBFBD>±<EFBFBD>‰<EFBFBD>γ<EFBFBD>π'ώCώωΏΠί¶<CEAF>Oϋό<CF8B>φω'λώΏάητϋόσOΪφ?η<>8<EFBFBD>Ηω?Ξ<>±<EFBFBD>!<21>έ|μμβ<7F>Ψ<EFBFBD>Δ<EFBFBD>‘<EFBFBD>%ψNΞιΐΏ><3E><1B>τ·wώϋώ‡ώφθξ<7F>υϊ_ϋOδϊW”Ζο{yΌ~<ώο§<^―<>YωωGα§ϊ_εϊ¬LλψΏwύ<77>ϋ<EFBFBD>kοΉϋΥύ<CEA5>uϊΏΣ<CE8F><CEA3>ΓOκ<4F>ο<EFBFBD>―ήωnύύ<CF8D><CF8D>a†ό+ω?RϋυΏ<CF85>wω<77>ΗΦ_―ύƒόC<CF8C>λΣ<ώ,¥<>ς?…Ϋϊ›#<23>Χ[<5B>ΨΘ?Λϋ[ψΟ³?ΗμYύύΟίOΏύ9<CF8D>ώRψωρώu<CF8E>»ίο™ϋ?©ώ_Οώ·¥<C2B7>Χγ<CEA7>{Ι?©ώΧί<CEA7>Ϋ–θ<7F>Υό£ςwfώ»ώ‘ϊΠ<7F>θό<7F>ψ<EFBFBD>ρ<EFBFBD>γ<EFBFBD>Η<EFBFBD>ώΰώΊρ<CE8A>–ό£yς½ψ<C2BD>-ωύmΣήώ3ήgϊχΟίοξψ<CF88><7F>ϋώ‡<CF8E>νπ?ώφ?-ώΗΨϋ©γsσο<CF83><CEBF>ύn<1F>£<EFBFBD>πΙ<CF80>#ώ―ωY{ύ<13>oΥΏi{nώόχΑ―<CE91>ΟΩ<CE9F>Θ<EFBFBD>ύΓ¤ϊ·]ώ¶<CF8E>—φ<E28094>³ν<C2B3>Σ¦ΛϊΏ¶<CE8F>ε;Χ<>¶ύ‹ύgΫώΓ<CF8E>Oό<1F>ψƒ?ωΏ#ρ<>q<EFBFBD><71><EFBFBD>ωΦσ‰<7F>qώ<71>σ―<CF83><E28095>g<EFBFBD>ΗωΞ<7F>#<23>°<EFBFBD>m<EFBFBD><6D>'<27>‡ό?μς<7F>ΰς<7F>Θ<EFBFBD>Γ<EFBFBD>‡<EFBFBD><0F>ϊ<>sυ?ό<0F>Γ<EFBFBD>Φψ<CEA6>λλε<CEBB>ςρ?<3F>οΕ)ΗwΫζΟΟΏϋΧkγ<6B>λ/Ύρώέΰ?!όmΗpZα?sαΗγ·-„ΚλψoΫΉ<CEAB>ΙΡ<CE99>δυ
|
||||||
|
ϋ•ψΏ<EFBFBD>±ώjπkλΏεωύη-αΣ?<3F><>m;χq°λπ΅<CF80>έθ?Ύ¶όΏ.Ύm|κωίy]’<>:Cώ―Ϋ<E28095>«ύμωw<7F>½<14>φΰW/½ΏήϊoΝ<6F><CE9D>ε?hλ?)ώηη>ϊζ<CF8A>ω<EFBFBD>;<3B>cυOΚ?φ?μ-Γο·<CEBF>Γ}<7D>tύ‡}3gμΏβηϋ<CF8B>Ώ·½<C2B7>Σξ?ΌξώΗ¦ύίC<43>ω<EFBFBD>¬υw?ω<><CF89><0F>ώΏOρ<4F>a<EFBFBD>Α<EFBFBD>Πί.ύµύ<C2B5>+^·ξ(ΟΟ\<5C>ηύΦ<CF8D>υψΛΰΧξ_φ<5F>φΖ¤ρ?mϋ«<1F>pώΞϊλωθ‰<CEB8>¬ζ<C2AC>o<EFBFBD>ΏΝ²<CE9D>W<EFBFBD><57>Y²<59>Ρ<EFBFBD>δiΖ―Wά<57>[<5B><>c<EFBFBD>Ω¶<CEA9><C2B6>ΫΖ<CEAB>ό?Ϋρ―Ρύ<CEA1>Ώήgζ?Υν<CEA5>rόσ<>τ<>ωήΉ1ύ<w<>·Ϊώώ_;<3B>Ωzώρ<>Oς<4F>®θ<C2AE>{ηώ«ί<C2AB>47ώCώ?ω<>+ΩΏ½φ<C2BD>4<EFBFBD>_;ώ‹<CF8E>LώΝ<CF8E><CE9D>Ώίώ'ώΠη¨πχΦ8κ3Ό^ξsψ»W=<3D><>χΗψπϋόύζΐ<CEB6>Η}¥<>όΑί6ώR<CF8E>§<14><>ό«αµ<7F>w~»ώƒώΠ_›ώ<E280BA>υο<><CEBF><EFBFBD>υΏnύ<6E>Ί<EFBFBD>aώΊυίΰψώ·‰?ϋ<>ώ
<0A>{ί{ο'…/ύ=ϋΏΦψ³”ώ«Ϊ<C2AB>ΟGΫz’ΖµΧΏv<CE8F>›µυ<1D>λ<>ΞύΠ<7F>Θ<EFBFBD>+δΏLώΞΛµκ<C2B5>C<EFBFBD>ΫΡ<CEAB>Πϊγ<CF8A>Gώsώψ<><CF88>αόOΟωοωΧλ<CEA7><CEBB>·<EFBFBD><C2B7>ΛωΞ<7F>sώ<73>σ<EFBFBD><CF83><EFBFBD>ηό?η<>9<EFBFBD><39>ύoλό?υΏm<CE8F><6D>ηόυ<>ακ<7F>sώίζωόψ<7F>π<EFBFBD>Yλ<59>Ωc<CEA9>ΝθΎξωψϋίfύό?ΰώvγ?τ΅<7F>τ·ξ<C2B7>Σλ<CEA3>½FύS›ώ?κ<>R<EFBFBD>W›<57>ο$<24>μΥ<CEBC>ύ,ωΗώ‡όwϊ?c<>c<EFBFBD><13>Ηώ'ώ<>ό§<CF8C>;ώ?θo%ώ<>ύ<07>Cκ<7F>S<EFBFBD><53>ϊ<EFBFBD>«Π<C2AB>ϊ—ο―<CEBF>7ξ―<>·Bύ—ώ-υχδώ<CEB4>5κ<35>Q<EFBFBD>Ϋ^ύτ?υ©<>f·ώφς<>ύ<EFBFBD>mωΏbύο5κ<35>[ο<>Sί<53>Ν©Ύ<7F>ύOύκ<7F>S<EFBFBD><53>ϊ<EFBFBD>–τ<E28093>JώΏwΦ<77>/ωΏjλoNώϊύ<><CF8D><1F>?ώό<7F>οΦ<CEBF>ΏίώόπrσΦ‡ώqίωί§ΗϋτO<CF84>—ΒOιΏpψƒ?ψΏ$•/ίω”“<E2809D>gω)Ε<><CE95>ΟΏί)ψuόΛγ·ν|=|ώ2ώcπ_<CF80>σσηΫ<CEB7>Πϊ―!<21>ό½dωsο_Ϋύξ<CF8D>ΏTώΟ›<CE9F><E280BA>ίϋgj¶ν<>uέο™ό<E284A2>†_Γ§6>uέ~ψώ·Μ<C2B7>ΰoΫώ‰<>ψώ»ίοφρ‡<CF81>9φ<39>hΒ΅<>'<27>—ω<E28094><CF89>ρχ}}ώµνYόgFύΫUβ?±Ώ?-Oγί<CEB3>~·<><C2B7><EFBFBD>ϋ½<CF8B>ϊoΗίχ»KΧ|Ώqψωρώυϊ<>ϊΝ~<7E>w?ΏωοΗ―ζι<CEB6>vωλλiύλϋ?mϊ<6D>Μϋψϊόk―Ώuμoμ?‹φώβ?ϊKρo΅_/όyτπ·‚Ώ―ΛΚ<CE9B>SυψJ9>s®—’<E28094><E28099><EFBFBD>ΗΏ4>¨ω|ϊώ)όΞ_όοΒη<CE92>ϋOµΔ―ZΰΛγ_RϊΛΦ<CE9B>¶IηΏοyΟΏ<CE9F>·ώΖθ―Γ<E28095>Rϋ†ύ«Y<C2AB><59>ΊόΧξ<CEA7>¦-<2D>eύί<CF8D>ύάΌ΄τΌ_ύΧ™ό<E284A2>όCώa<CF8E>―c<E28095>Ο°?Gμ<47>ϋγ/¥?φ?φ?ό<0F>λςΏ]όΡ<CF8C>ψ<EFBFBD>π<EFBFBD>΅<EFBFBD>mλψώ‡<CF8E>νπΏυόGΖsώ<73>σ<EFBFBD>γω“<CF89>υ§<CF85><C2A7>IώτΧ„Ησ/3Ο<33>¬sώΟζωW<CF89>^aφτώ Oiώϋω<CF8B>Ϊώ¨η:ω<>³ΞΏ¥Ώo9<6F>·ΖωΞ<>qώ<71>ύϋ_[γ9<CEB3>CύΞ_£<5F>8<EFBFBD><38>όΗ<CF8C>ƒ<EFBFBD>ϊΫς<CEAB>a<EFBFBD>Α<EFBFBD>Π<EFBFBD>ϊ/Τ<>³^<5E>i^ύ‘<1E>ηΧ<>LόW<CF8C><57>'‹<><E280B9>Ε<EFBFBD>Φ©<CEA6>”ΖΏζ<CEB6>W<EFBFBD>GΗ<47>/<2F><>Ν³?uβΔ<7F>Ρ<EFBFBD>Τ¦ώρμ?‹φρoδ?ωvγ_#ϋΏγwsλΏκτ<CEBA>΅ώ?υ<>Ι<EFBFBD>#ώ<><CF8E>WΗ<57>·Nύ©ώ‘ΖΘ<7F>'<27>_7<5F>_f<5F><66>ε<EFBFBD>―S<E28095><1F>?ύ?Ε<C2AD>_OτΆ‡<CE86><E280A1>ρ|ιλ<CEB9>^<5E>sί¦―Χξ<1F>—Β―έΏχωΐό?<17>W-’°ώIωsψ’β~…πjψΧΖΧ_e|ϋαχήϊCϊkΧ?Ό;ώ<>υΏ^ύλZύ«s«9ψλΤƒ<7F>αψί.ώΦν<CEA6>Γσχϊ/sπ<73>λεO<ξ<1F>>bό<62>λgϊΏ~?ώ<19>>τχιΏmηώ79}χΉ‘<CE89>_ΫώoΑΏ¶ώrσΫ#ξϋp>5ΧΏv<CE8F>›ΦΏ<04>ςοΞύΠ<7F>Θιϊϋ¦Ν<C2A6>Ώgω<67>–Λμ<CE9B>Π<EFBFBD>θθo—ώψ<CF8E>‰<EFBFBD>Tν®s<C2AE>ψ<EFBFBD>‡Ϊ<E280A1>#ρ<>ΈΙψωΛ1ωΫ7ΎlΟΘϊΏHε<48>=γ}τ©ο<C2A9>{η_2ώόό<CF8C>λO[Ύ<>ω<EFBFBD>]>qlίηΖ—ύ<E28094>zπ‘<CF80>#ϋΏp?#<23>]ω?²<>Χ_Λό•χwγΏyώoβ<6F>Δ?±<>ο–<CEBF><E28093>^?µ-<2D>GΣώΡ}~νω'<27><>ό?ψ<>ό?«ςΟΊ<17>ώ?ό–ύ2ϋoFώΏnόώΗώΗώΧ:<3A>sχσ/ΰώ<>…<EFBFBD>{υΏ¶ό—κ<E28094>4όπ»ϊώ ϊC-ϊKλmΫωϋη#]_κωHΧ³ZγόΛXύ«yς_
|
||||||
|
_Z<EFBFBD>φL<EFBFBD><EFBFBD>?<3F>t–Φ?σy ―<15><>ψ<EFBFBD>ίωόW‰<57>[Φίλ=Ε<>ΟΗ™<CE97>µΧΏ6<CE8F><EFBFBD>ό―<>χ|Μ<><CE9C>Τόϊσ<CF8A>®gSώa<CF8E>«Η<C2AB>Ϋψ?φ<>ημ<CEB7>¤ύΣ®θΏφΞυo]<5D>iΣΟϊϊ»<CF8A>ό<EFBFBD><17>Χ<EFBFBD><CEA7>"<22>΅<EFBFBD>Zπ±<CF80>°<EFBFBD>π<EFBFBD>C<EFBFBD>χϋΏθi»<69>#ύ_-®ϊ<7F>Π<EFBFBD>‡ώ?Vϋ<56> <20>Π<EFBFBD>²ϊ―σϊ<CF83>jΛλύ±<7F><C2B1>φδςV<7F>λ1ϋ<CF8B>υ/νΏ+¥<>}ϊ<>¦χRύ―c<E28095>£<EFBFBD>uω<75>sδ<73>T<EFBFBD>λμ<CEBB>Λ?τΏ®<CE8F>―<EFBFBD><E28095><&gζ<67>·λ©<>ύ<>ώΗ<CF8E><CE97><EFBFBD><1F>?ώόΰώΰ=ώ<>σOσδΏ<CEB4>ώ·.<2E>΅?ϊ<CF8A><7F>§}?Ί’<CE8A>ΟΊ<CE9F>ϋώ‡<CF8E>ρƒ?ωίώΗ}ύ<>γsρ/Mψ#τ<>¤ρδ<CF81>α<EFBFBD>ο<EFBFBD>ηόωµρΉψ<CE89>λ<>ψΏμ³”~³<>ηέΟoGώ»υ<S<>·Λ__<5F>o[ϋσηκΟqώC<CF8E>ώ#σί>Ύ><3E>ΪλoϋϋΟΆύ‡<CF8D><1F>ρ_πλρiόgΜΏΌ<CE8F>ό·™<C2B7>Kό<4B>ύη_‰<5F>°<EFBFBD>γό?η<>‘Ψ<7F>Vρ'<27>‡ό?μς<7F>ΰς<7F>Θ<EFBFBD>Γ<EFBFBD>‡<EFBFBD><0F>ϊίΞω/ψώ‡<CF8E>mρ<6D>λ‰^τπρ?<3F><>λ\?_wςσυ?χmϊzνώρx)όΪύ{<7B>ο³ρυ" ϋ<>τ|–®/ιύ¥Οί?<3F>ΏΪ«vθ/ϊΟ…―)ίεωίςόη――W>³?>χόώύ<CF8E>Α?®ΧΖΧΟψΛς_¥ς¥ώO®}Ύ<>Uόϋωσ<CF89>ξώ{_<1F>¦Φ_mΌ=ζύυ/Ν<><CE9D>ε?hλ?)ώΗύΓω?ζΉuώ<75><CF8E>Ήσ?V<>ΤΆόΓώgkύzΏύΎ¤λ«¶_κί•<7F>·φΉϋ?νώΓϊϋλφΏ.ύ¬―Ώ{Κόψ<7F>π<EFBFBD>}‚<>ϋώ‡ώ–ν}<7D>£&|λφίΨόΟσήsύΟυ<CE9F>ώϋw.ό3ώ!όyρiόOΫώΓ?<3F>Gr~όXώ—β?kω<6B>ϋβgσχ<CF83>ο<EFBFBD><CEBF><11>G<EFBFBD>[<5B><>΄ΔΏcyΛ3ιόkΛλρμ?»φρoδ?ωvγ_’ύ<E28099>Σ<EFBFBD>ωwμO¶έώOΕ?KγƒλΡ<CEBB>Gτ<47>άύίjϋ<6A>wς<77>=σ<>η<C2AD><11><>$<24>―¦<E28095>O<4F>5β<CEB2><17>!<21><>ό<EFBFBD>Υς<CEA5>{μΏω<><CF89>ρ_ό<5F>#ό3/ώ―c<E28095><13>?Ζu$γχ―Μ+χ»ΪψΪχΐ>πί?νx>rς%φ?\
Ώ†Ϋώ»μ<C2BB>Π„ύ΅Ώ6ύΟυ§γϊΥξ<CEA5>cυ―συ§ο<C2A7><CEBF>έη?½<><C2BD>χoΞο?ζΰ<CEB6>‡_ΗΏe<CE8F>YΪ<59>ΐ<EFBFBD>πΏuώ·‹?ϋ<>4|λοΦχΞΏXΎ.<2E>ηUν<55>Vό΄ηoΖό§ε―“³ρυηcήψuυΏμωο2<CEBF>θδ<7F><CEB4>ς<EFBFBD>]ς—ύϊίΊώ‡ώΠ<1F>Ώeωoϋό3ψ<33>σ<EFBFBD>Υόόλαkζ<6B>ΕyssΞ_<CE9E>σ<EFBFBD><CF83>yyιό;―Zό«-<2D>―~OόmFόKχόOjώΫσ/Sψ§σ<C2A7>άσrώ§®<C2A7>BϋuίeϋλΪύ<CEAA><CF8D>Ήπχ}Φώί‚ό?<>κη³Ό’Π_[ώΧπΏάΌ΄Ξη<CE9E>λ_ϋΊ6<CE8A>έ}ώ<>ΐΏξόοΌώχ<<3C>όIη[χ?ιύΚ<CF8D>υ7Ύ<37>JΫ<4A>©ρ%ϋ<>?wΎiΜώ/ΫπΏ6<CE8F><36>οΏ―X<E28095>Ϊϋkς<6B>ϊ<EFBFBD>ψ<EFBFBD>π<EFBFBD>α<EFBFBD>³[<5B>gάώ›±ώ΄ν/ψϋί¶ύ―Ύώ€|ΰίPώΏώuς5ψΠϊkΠ<6B>όώχσΞλq|*w=Δήψπύ8WβζίΥΚςοΥόχΓ/<2F>χΏί6<CEAF>άL–><3E>οsηί―<CEAF>8‚<Ύφύy<1F>Γ―¶ώZΗη>―±ώµω<C2B5>~ςοξσo]ώΩµ<CEA9>uγϊρoλψc<CF88>Ϋ¶<CEAB>χ=”<>nύψυaΗε―<E28095>ίοπώ묻ϊoύ¥ςoήϊ‹Η·α<C2B7>ώΣ‰<CEA3>kΗ‘<7F>Φι?^<5E>½<EFBFBD>ώaό?ξ?€ύ‡ύ‡<CF8D>ϊλΡΕϊSχ¨¥]σ:ψΦηί<CEB7>ϊ—ϊ<E28094>¥οΊυ<CE8A>εψIύ<49>Ϊο<12>ΓΌϊγiψρ_όόΧϊ<CEA7>ί³ώ<C2B3>θ<7F>Υκ<CEA5>χΛ/©ώΡ–<CEA1>)όΗ<CF8C><CE97><EFBFBD>σ<07>!<21><>ΐ—ΑΧ~Χ^<5E>α{«ύyΥόχΓ/<2F>/}?g<>7w<37>©m<C2A9>ΫΣ<CEAB>kρ<6B>ύδίέηί®όc<CF8C>·<EFBFBD><C2B7>ο<EFBFBD>ςw<CF82>ώ‘ϊΠ<7F>θό<7F>ψ<EFBFBD>ρ<EFBFBD>γ<EFBFBD>§<EFBFBD>π<>|ϊΏΣ<CE8F>ϊCϊΣ<7F>ϋ½ρ<C2BD>¶όΣ9ψλΪίπ?όo›<6F>ι<EFBFBD>k{<7B>±οαψΪηήχήϋIαKό/χylώέύkχ›?O<>_ϊΏ–ϊΟ»~AΗϊ γϋ.‹?Δγλό<CEBB>Ξυ/‰<>Μ™νψO<CF88>ώ‡ώ<®<>κ<EFBFBD>ΌόK?;ό΄ώ<CE84>ΗΧτΏuω?ή<>O<EFBFBD><4F>kύΛjϊόκώVϋ?kΣΫΪΦ<CEAA>Υύ/ΗΦ_{<7B>Cmϋϋϋ<0F>?ρϊ/ψVϋ<CF8B><7F>‡ώ?τ<>±Ϊ<C2B1>‡ώΧ¶ε½}ω]:<3A>Ϊό'ΕO{ώΰ?δςψwν<77>wgό?±<>"φ?ύ?α»όo
τ?ώ?όθτ?ό<0F>Γ<EFBFBD>–ψίzώ#ψsώ…σ<E280A6>ϋ^Ξ<><ΎΝ<>*ηλη’<7F>k›ώϋ>~L<>}α»ϋ―qώe½σ?οΜζόo®<6F>ex>(UΏlFώ©<7F>]ύό<CF8D>Ό<EFBFBD><CE8C>υόΝσgλ<67><CEBB>·tώ<74>σ<EFBFBD><CF83><EFBFBD>g<EFBFBD>ΟωΞ<7F>Ψ¬<CEA8>3~ώ»MώΊϋϋ6Χ:ϋμΞ<7F>sώ<1F>ώ?όφόΨ<CEA8><7F>†ώ6ιOύ?ό+Τ!YΝ<59>fε]<1A>‘Ζ<E28098>V°<56>¤ύ<C2A4>¤ηοV©<56>—<EFBFBD><E28094>ΧGλΧφ<CEA7>λΕ<CEBB>¬Ψ<C2AC>θςΏ¨<CE8F>g7ώ<37>ύgΫώ#ώ<>ό'<27>ΟnόKΪΏtΞώs½ώ?Τ<>§ώ?υ<>‰<EFBFBD>[<5B><>―θ<E28095>{gύ‰ώ™sώ•ός<7F>5νί9ύλGυ<47>vό<17>?ύ?νζ„τ=<3D>/G<>σό1<CF8C>ρ<EFBFBD>Ώ<EFBFBD>ψΈ.IΊώΛΉ~Κ»ΰ_ύόΪπ΅?τΧ•ηχίοw^Ώ;ώχ<CF8E>ι<7F><CEB9><EFBFBD>kχΏφωαψί2<CEAF>ƒΏMϋ<4D>ήυ§επ΅ΏnύWmύ«_tώίsςΣ<CF82>]Ώ<ή<>~%ω;<0F>»Ο?ϊω―Q<E28095>[WώZί<5A>΅<EFBFBD>Ρ<EFBFBD>Πί.ύρ<CF8D>γ<EFBFBD>sη;<3B>σ‰Ήσ<CE89>cπγρξ|VzΌ~*<2A>ό‰3Ύ΄ώΓ½bιso|Ζ<1F>ΚE=ΦgZ~Ίί·―<C2B7><E28095>ψ6ω/<2F>?IεΏήώwύeςoΫΪΰ·Δ<C2B7>Z<EFBFBD>χόϋyλ/e3»ϋψηυ<CEB7>;εΏ¬ώC›ύιξ¦9<7F>{~Oώ7ώ<37><CF8E>ώ¥υ?¶<>+Ρ_[ώ<>γίΎ<CEAF>σρ<CF83>ω_{ύ[<5B>Ώ<11>ΔώΕώ/Ϋη-φ—ΤώΧί<CEA7>Kρ—ξ<E28094>ηΝz~Ι<>#<23>ώ'<27>―<EFBFBD>><3E>.<2E>πγ<7F>Γ<EFBFBD>‡<EFBFBD>ΟΆ<CE9F>o<EFBFBD>ύ'=Ά<1D>µΛ<C2B5>Ψ<EFBFBD><CEA8><EFBFBD>a<γΟωςΏ8<CE8F>ύ-ζλ<7F>?Y'ώeΣ<65>—£i―<69>ϊ<EFBFBD><<3C>XΗώ'<27><>σ<CF83><7F>γόρς<7F>-η<>c<EFBFBD><13>'ώOό<4F>ψΏmύW‹<E280B9>Θ―¶ψ―vό<76>σ<EFBFBD>VιOόϋ<0F>?τ·κ<C2B7>Χξ?£ <09>οΎ‹aΖΧ?kΌυω·Ύώ¥ώg?<3F>δχ£qt ―Ηί—εW<CEB5>~Wϋ<57>sxΜτ<CE9C><CF84>ύΤη―6ΟςωσHω―ύώιΏkύ7Χ―?δϊ_›ώ’ψ³tώΧ‘<CEA7>ZύΗΰ?δς<>ρΪλ_Ηώ\gύK<CF8D>¤τΣω›·<E280BA>“κϋύ―Λ<E28095><CE9B>#<23>ξ><3E>6εϊ_Χ<5F>§-ηι©<>ύ<>ώΗ<CF8E><CE97><EFBFBD><1F>?ώό_ΐ>πί©<CEAF>uβ?+Ψ_ΨΠ<1F><>M<EFBFBD>Ώu<CE8F><75>φώήώλ<CF8E>ϊπ?ό<>ωόώ¶ν<C2B6>}Ηί½>ΗΧCψΉη/<2F>ίχςx)όxόίOy|<0E>cώ<63>λ£σοξ|ώ#O)όxό<78>ύνσSx=΄<>[θ_›<5F>νισΏsώ¤γΏ΄}ξ}o»<6F>ήϊΕk.ύτήsτωύ><3E>§Ρ<>mςO
|
||||||
|
??Ύ¦<CE8E>Λ<C2AD>\<5C>Ώp>ΗεWM<57>ηϊ<CEB7>µκ<C2B5>όψ6ωk}<7D>·*ύ[Φ<><CEA6>ώwϋ>wύ=εωsχ[ΓώΕώ³m<C2B3>α<EFBFBD>Η<EFBFBD>|ΰ<03>σ<EFBFBD>Φςη<C2AD><11>C<EFBFBD>kΫ<6B>+<2B>·<EFBFBD><C2B7>ΕώΟΞώώcώ±ΏΓ'<27>‡ό?μς<7F>ΰς<7F>Θ<EFBFBD>Γ<EFBFBD>‡<EFBFBD><0F>ϊ<>σ<EFBFBD>π?ό<0F>.<2E>}½ς±όό§£?ΛλI<CEBB>ο¶Νχoώ»ίλϊ¶…γ_xϊγ<CF8A>λGΧ<>ευϋΉπγρξϊQ<CF8A>Α<EFBFBD>π>ΚΟοF<CEBF>αό•αύ<>\<5C>bΧ<62>θθ‡δϊ…}<7D>g¬<67>°oς~mύ<6D><CF8D>+~ώ°<CF8E>rκϋ^~yώsσ<73>
|
||||||
|
ϊkΣίηΒ<CEB7>αΈϋ§ζS[ώΛσΏeωΟ)όΓλ±~~>ϊΖ<CF8A>ωλω<CEBB>“<EFBFBD>:ƒ<>τϋΏ<CF8B>ΧhO§ιοΓ+Σηl_•ζΏΤ―<05>t<EFBFBD>?ΗΟG<CE9F><47>c~(α—<CEB1>¥ϋ<C2A5>οΏβϊ—<CF8A><E28094>i―<E28095>®xώ;ΝΏuωΗώƒύΏeόkϋ<6B><CF8B>~iΞώCw<43>e}<7D>—·<E28094>Ού‡Ηδ―Ώ<E28095>‰ϋ?―°<E28095>Αώ¥<>ωW:<3A>;¶ώϊΞ<CF8A>"<22>ρ<EFBFBD>α<EFBFBD>Γ<EFBFBD>gΥ<67>‡ύg<CF8D><67>΅ΏeϊΧό³ύώΗ><3E>―¶<E28095><13>‡ΜyΕum<75>›6ώοΌ.<2E><>HγΪφί9ώ”ΚGΛϋΟλρ<CEBB>ς»Ύ<C2BB>ίGβo³μ<C2B3>γ–μτ?ω_=ρκm›<1B>_q<5F>o)ώ<>ύgΫώ#ώm>ω¶γ_£ϋ<C2A3>vύί—<CEAF>τzwΪΊ7ώ™_²<5F><C2B2>‰}#έ<>¶<C2AD>_<EFBFBD><5F>υγ<CF85>–ς<E28093><CF82><EFBFBD>[φ<>®θ<C2AE>“νΏφ]βλΡ?3β?δ<>“<EFBFBD>ΏRώ―ύ'Υ?ΪρWό<57>-ς/=_Wδ?^o<><13>?®υβχ―Μ+χ»ΪψΪχΐ>πί_*®†_Γ<5F>j<EFBFBD>λΥπ΅?τΧ¦Ώfύ΅»γχω—ϊζΰ―[ώ‡<CF8E>mσΏ]όΩ¤α[·Ύ<C2B7>kυKηyUϋΏ?νω›1<E280BA><31>ύgΦΥ<CEA6>²ηΏΛό£<CF8C>‘<EFBFBD>+Κ<>wΙ_φθλϊϊCό<7F>–ε?υ<>8<EFBFBD>ΟωΞ<>τ<EFBFBD><CF84><EFBFBD>Q<EFBFBD>oΝσ<CE9D>δ<EFBFBD>rώ<72>σ<EFBFBD><CF83><EFBFBD>ηό?η<>9<EFBFBD>ΟωΞ<7F>c[;<3B>o¥ώ7η<37>9<EFBFBD>Cύκ<7F>S<EFBFBD><53>σ<EFBFBD><CF83><EFBFBD>Η<EFBFBD>‡<EFBFBD><0F><>¥ώ<C2A5>γφί<CF86>υ·ζωKό<4B>ύo»ώ?π<>|»ρϊΏΠ<CE8F>ϊΫυ<CEAB>Χ<C2AD>ϋ½υOϋ<C2AD>¨<EFBFBD>k»ώοzό'ωw<CF89>ϊΏ¶εϋς<>mχΖώ'ώOό<4F>ψ?ρ›ςίz<CEAF>wλώ?λτ·<1D>ΗώΓ<CF8E>ύ©<CF8D>Ο;υ™[οsόΗ²ϊsΪυ_Jψ<4A>><><7F>_»ώυΏΦ<C2AD>AίS<CEAF>‘ϊovλΏΑΜ7ϋΫςΕϊίϊυΟχ<C2AD>iΫ<69>]·<>Τµ<CEA4>©<EFBFBD>Oύκ<7F>S<EFBFBD>ί†ώ_Ο<5F>χΞϊ<CE9E>ύ3Η<33><CE97>ώG<CF8E>γ<EFBFBD>Η<EFBFBD><CE97><EFBFBD><1F><>»υ<C2BB>΅?<3F>N<EFBFBD>η<Ύ<1E><>ρ<EFBFBD>gό]Η‡ςύ<CF82>O9ω–<7F>ΧΒΏώωµαCθΏ†όΠώ»;ώχ<CF8E>·>Οο-ΧηρνώΧ<?ό<0F>[ζπ·m<C2B7>»σ<C2BB>ΞΰΞOϊΏχ?»ϋϋg.σώo)όx|Ι<>ύϋνί<CEBD>υΚΓ›<>xΌ<78>jΌ~
|
||||||
|
<EFBFBD>ύ%η<>¥ρmύ«οΤ<7F><CEA4>μ{θοwλΗηχίοόϋ]ώή|ί_{ύ<>ύ”<CF8D>?Ζ%<25><>ψόΟ<CF8C>__Ίo‰ήyzµλΟ6ω'…/ύ½]ω/©<>1C<31>ηλ?ΤυΏ΄ώƒυύ<CF85>6ύSσΧ³ώΛγΫτ<CEAB>ΎΟ]}υotν_μ?Ϋφώβ?βωc<γλρ<CEBB>?iό%®‹’®<E28099>\zώςψπZό;9~Rψςψ•tώ¥τΏvύ]ύόΪλO‹<4F>Χ«?<3F>^ψΦεΏv<CE8F>7mώΣο? |