mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
ADD: iso11784/85 FDX-B
ADD: the source from RevEng 1.30, got into the PM3 client.
This commit is contained in:
+7
-6
@@ -113,13 +113,14 @@ CMDSRCS = nonce2key/crapto1.c\
|
||||
pm3_bitlib.c\
|
||||
aes.c\
|
||||
protocols.c\
|
||||
cmdcrc.c\
|
||||
sha1.c\
|
||||
# reveng/reveng.c\
|
||||
# reveng/cli.c\
|
||||
# reveng/bmpbit.c\
|
||||
# reveng/model.c\
|
||||
# reveng/poly.c\
|
||||
cmdcrc.c\
|
||||
reveng/reveng.c\
|
||||
reveng/cli.c\
|
||||
reveng/bmpbit.c\
|
||||
reveng/model.c\
|
||||
reveng/poly.c\
|
||||
reveng/getopt.c\
|
||||
|
||||
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
||||
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
||||
|
||||
+47
-21
@@ -10,33 +10,59 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "cmdparser.h"
|
||||
//#include <stdlib.h>
|
||||
//#include <ctype.h>
|
||||
#include "cmdmain.h"
|
||||
#include "cmdcrc.h"
|
||||
//#include "reveng/reveng.h"
|
||||
//#include "reveng/cli.h"
|
||||
static int CmdHelp(const char *Cmd);
|
||||
#include "reveng/reveng.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
|
||||
int CmdCrcCalc(const char *Cmd)
|
||||
{
|
||||
//pm3main(Cmd);
|
||||
return 0;
|
||||
#define MAX_ARGS 20
|
||||
|
||||
int split(char *str, char *arr[MAX_ARGS]){
|
||||
int beginIndex = 0;
|
||||
int endIndex;
|
||||
int maxWords = MAX_ARGS;
|
||||
int wordCnt = 0;
|
||||
|
||||
while(1){
|
||||
while(isspace(str[beginIndex])){
|
||||
++beginIndex;
|
||||
}
|
||||
if(str[beginIndex] == '\0')
|
||||
break;
|
||||
endIndex = beginIndex;
|
||||
while (str[endIndex] && !isspace(str[endIndex])){
|
||||
++endIndex;
|
||||
}
|
||||
int len = endIndex - beginIndex;
|
||||
char *tmp = calloc(len + 1, sizeof(char));
|
||||
memcpy(tmp, &str[beginIndex], len);
|
||||
arr[wordCnt++] = tmp;
|
||||
//PrintAndLog("cnt: %d, %s",wordCnt-1, arr[wordCnt-1]);
|
||||
beginIndex = endIndex;
|
||||
if (wordCnt == maxWords)
|
||||
break;
|
||||
}
|
||||
return wordCnt;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"calc", CmdCrcCalc, 1, "{ Calculate CRC's }"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdCrc(const char *Cmd)
|
||||
{
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
char name[] = {"reveng "};
|
||||
char Cmd2[50 + 7];
|
||||
memcpy(Cmd2, name, 7);
|
||||
memcpy(Cmd2 + 7, Cmd, 50);
|
||||
char *argv[MAX_ARGS];
|
||||
int argc = split(Cmd2, argv);
|
||||
//PrintAndLog("argc: %d, %s %s Cmd: %s",argc, argv[0], Cmd2, Cmd);
|
||||
reveng_main(argc, argv);
|
||||
for(int i = 0; i < argc; ++i){
|
||||
//puts(arr[i]);
|
||||
free(argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd)
|
||||
{
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12,5 +12,4 @@
|
||||
#define CMDCRC_H__
|
||||
|
||||
int CmdCrc(const char *Cmd);
|
||||
int CmdCrcCalc(const char *Cmd);
|
||||
#endif
|
||||
|
||||
+16
-24
@@ -25,7 +25,6 @@
|
||||
#include "crc.h"
|
||||
#include "crc16.h"
|
||||
|
||||
|
||||
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||
uint8_t g_debugMode;
|
||||
size_t DemodBufferLen;
|
||||
@@ -500,7 +499,7 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose)
|
||||
{
|
||||
//ask raw demod GraphBuffer first
|
||||
int offset=0, clk=0, invert=0, maxErr=0, ans=0;
|
||||
ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
|
||||
ans = sscanf(Cmd, "%i %i 0 %i", &offset, &clk, &maxErr);
|
||||
if (ans>0)
|
||||
ans = ASKDemod(Cmd+2, FALSE, FALSE, 0);
|
||||
else
|
||||
@@ -1487,7 +1486,7 @@ int CmdFDXBdemodBI(const char *Cmd){
|
||||
|
||||
errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0);
|
||||
if ( errCnt < 0 || errCnt > maxErr ) {
|
||||
if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: 32", errCnt);
|
||||
if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: %d", errCnt, clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1505,7 +1504,8 @@ int CmdFDXBdemodBI(const char *Cmd){
|
||||
|
||||
setDemodBuf(BitStream, 128, preambleIndex);
|
||||
|
||||
size = removeParity(BitStream, preambleIndex + 11, 9, 2, 128-11);
|
||||
// remove but don't verify parity. (pType = 2)
|
||||
size = removeParity(BitStream, preambleIndex + 11, 9, 2, 117);
|
||||
if ( size <= 103 ) {
|
||||
if (g_debugMode) PrintAndLog("Error removeParity:: %d", size);
|
||||
return 0;
|
||||
@@ -1515,42 +1515,34 @@ int CmdFDXBdemodBI(const char *Cmd){
|
||||
PrintAndLog("DEBUG BinStream:\n%s",bin);
|
||||
}
|
||||
PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:");
|
||||
if (g_debugMode) PrintAndLog("startmarker %d; Size %d", preambleIndex, size);
|
||||
if (g_debugMode) PrintAndLog("Start marker %d; Size %d", preambleIndex, size);
|
||||
|
||||
//got a good demod
|
||||
|
||||
//marshmellows
|
||||
//got a good demod
|
||||
uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(BitStream+32,6)) << 32) | bytebits_to_byteLSBF(BitStream,32);
|
||||
uint32_t countryCode = bytebits_to_byteLSBF(BitStream+38,10);
|
||||
uint8_t dataBlockBit = BitStream[48];
|
||||
uint32_t reservedCode = bytebits_to_byteLSBF(BitStream+49,14);
|
||||
uint8_t animalBit = BitStream[63];
|
||||
|
||||
uint16_t crc16 = bytebits_to_byteLSBF(BitStream+64,16);
|
||||
uint32_t crc16 = bytebits_to_byteLSBF(BitStream+64,16);
|
||||
uint32_t extended = bytebits_to_byteLSBF(BitStream+80,24);
|
||||
|
||||
uint64_t rawid = ((uint64_t)bytebits_to_byte(BitStream+32,32) << 32) | bytebits_to_byte(BitStream,32);
|
||||
uint64_t rawid = ((uint64_t)bytebits_to_byte(BitStream,32)<<32) | bytebits_to_byte(BitStream+32,32);
|
||||
uint8_t raw[8];
|
||||
num_to_bytes(rawid, 8, raw);
|
||||
PrintAndLog("%s", sprint_hex(raw,8));
|
||||
uint16_t crcCalc = crc16_ccitt_rev( raw ,8);
|
||||
|
||||
PrintAndLog("Animal ID: %u-%012llu", countryCode, NationalCode);
|
||||
|
||||
if (g_debugMode) PrintAndLog("Raw ID Hex: %s", sprint_hex(raw,8));
|
||||
|
||||
uint16_t calcCrc = crc16_ccitt_kermit(raw, 8);
|
||||
PrintAndLog("Animal ID: %04u-%012llu", countryCode, NationalCode);
|
||||
PrintAndLog("National Code: %012llu", NationalCode);
|
||||
PrintAndLog("CountryCode: %u", countryCode);
|
||||
PrintAndLog("CountryCode: %04u", countryCode);
|
||||
PrintAndLog("Extended Data: %s", dataBlockBit ? "True" : "False");
|
||||
PrintAndLog("reserved Code: %u", reservedCode);
|
||||
PrintAndLog("Animal Tag: %s", animalBit ? "True" : "False");
|
||||
PrintAndLog("CRC: 0x%02X", crc16);
|
||||
PrintAndLog("CRC : %X == %X %s", crc16, crcCalc, ( crcCalc == crc16 )?"ok":"!" );
|
||||
PrintAndLog("Extended: 0x%X", extended);
|
||||
PrintAndLog("CRC: 0x%04X - [%04X] - %s", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed");
|
||||
PrintAndLog("Extended: 0x%X\n", extended);
|
||||
|
||||
/*
|
||||
//uint16_t crcCalc = crc16_ccitt( ByteStream, 8);
|
||||
PrintAndLog("Application ID: %04X", applicationid);
|
||||
*/
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-2
@@ -32,9 +32,9 @@ unsigned int current_command = CMD_UNKNOWN;
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
static int CmdQuit(const char *Cmd);
|
||||
static int CmdRev(const char *Cmd);
|
||||
|
||||
//For storing command that are received from the device
|
||||
#define CMD_BUFFER_SIZE 60
|
||||
static UsbCommand cmdBuffer[CMD_BUFFER_SIZE];
|
||||
//Points to the next empty position to write to
|
||||
static int cmd_head;//Starts as 0
|
||||
@@ -44,11 +44,11 @@ static int cmd_tail;//Starts as 0
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help. Use '<command> help' for details of a particular command."},
|
||||
{"crc", CmdCrc, 1, "Crc calculations from the software reveng1-30"},
|
||||
{"data", CmdData, 1, "{ Plot window / data buffer manipulation... }"},
|
||||
{"hf", CmdHF, 1, "{ High Frequency commands... }"},
|
||||
{"hw", CmdHW, 1, "{ Hardware commands... }"},
|
||||
{"lf", CmdLF, 1, "{ Low Frequency commands... }"},
|
||||
{"reveng",CmdRev, 1, "Crc calculations from the software reveng1-30"},
|
||||
{"script", CmdScript, 1, "{ Scripting commands }"},
|
||||
{"quit", CmdQuit, 1, "Exit program"},
|
||||
{"exit", CmdQuit, 1, "Exit program"},
|
||||
@@ -70,6 +70,12 @@ int CmdQuit(const char *Cmd)
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdRev(const char *Cmd)
|
||||
{
|
||||
CmdCrc(Cmd);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief This method should be called when sending a new command to the pm3. In case any old
|
||||
* responses from previous commands are stored in the buffer, a call to this method should clear them.
|
||||
|
||||
+5
-1
@@ -11,7 +11,7 @@
|
||||
#ifndef CMDMAIN_H__
|
||||
#define CMDMAIN_H__
|
||||
|
||||
#include "../include/usb_cmd.h"
|
||||
#include "usb_cmd.h"
|
||||
#include "cmdparser.h"
|
||||
void UsbCommandReceived(UsbCommand *UC);
|
||||
void CommandReceived(char *Cmd);
|
||||
@@ -19,4 +19,8 @@ bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeou
|
||||
bool WaitForResponse(uint32_t cmd, UsbCommand* response);
|
||||
void clearCommandBuffer();
|
||||
command_t* getTopLevelCommandTable();
|
||||
|
||||
//For storing command that are received from the device
|
||||
#define CMD_BUFFER_SIZE 50
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/* bmpbit.c
|
||||
* Greg Cook, 9/Apr/2015
|
||||
*/
|
||||
|
||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
||||
*
|
||||
* This file is part of CRC RevEng.
|
||||
*
|
||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CRC RevEng is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef BMPTST
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# define FILE void
|
||||
#endif
|
||||
#include "reveng.h"
|
||||
|
||||
#if (defined BMPTST) || (BMP_BIT < 32)
|
||||
/* Size in bits of a bmp_t. Not necessarily a power of two. */
|
||||
int bmpbit;
|
||||
|
||||
/* The highest power of two that is strictly less than BMP_BIT.
|
||||
* Initialises the index of a binary search for set bits in a bmp_t.
|
||||
* (Computed correctly for BMP_BIT >= 2)
|
||||
*/
|
||||
int bmpsub;
|
||||
|
||||
void
|
||||
setbmp(void) {
|
||||
/* Initialise BMP_BIT and BMP_SUB for the local architecture. */
|
||||
bmp_t bmpmax = ~(bmp_t) 0;
|
||||
|
||||
bmpbit = 0; bmpsub = 1;
|
||||
|
||||
while(bmpmax) {
|
||||
bmpmax <<= 1;
|
||||
++bmpbit;
|
||||
}
|
||||
|
||||
while((bmpsub | (bmpsub - 1)) < bmpbit - 1)
|
||||
bmpsub <<= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BMPTST
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
/* check the compile-time bitmap width is correct, otherwise
|
||||
* searches run forever. */
|
||||
# if BMP_BIT > 0
|
||||
setbmp();
|
||||
if(BMP_BIT != bmpbit || BMP_SUB != bmpsub) {
|
||||
fprintf(stderr,"reveng: configuration fault. Update "
|
||||
"config.h with these definitions and "
|
||||
"recompile:\n"
|
||||
"\t#define BMP_BIT %d\n"
|
||||
"\t#define BMP_SUB %d\n",
|
||||
bmpbit, bmpsub);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
# endif /* BMP_BIT > 0 */
|
||||
/* check the bitmap constant macro */
|
||||
if(~(bmp_t) 0 != ~BMP_C(0)) {
|
||||
fprintf(stderr, "reveng: configuration fault. Edit "
|
||||
"the definition of BMP_C() in config.h to "
|
||||
"match BMP_T and recompile.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
#endif /* BMPTST */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,92 @@
|
||||
/* config.h
|
||||
* Greg Cook, 9/Apr/2015
|
||||
*/
|
||||
|
||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
||||
*
|
||||
* This file is part of CRC RevEng.
|
||||
*
|
||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CRC RevEng is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H 1
|
||||
|
||||
/*****************************************
|
||||
* *
|
||||
* Start of user configuration options *
|
||||
* *
|
||||
*****************************************/
|
||||
|
||||
/* A type to contain polynomial coefficient bitmaps.
|
||||
* Can be changed to 'unsigned long long' for some extended compilers.
|
||||
* Adjust BMP_C(), BMP_BIT and BMP_SUB below if this is changed.
|
||||
*/
|
||||
|
||||
#define BMP_T unsigned long
|
||||
|
||||
/* Creates an appropriate numeric constant for bmp_t.
|
||||
* If the underlying type is 'unsigned long long', change UL to ULL.
|
||||
*/
|
||||
|
||||
#define BMP_C(n) (n##UL)
|
||||
|
||||
/* Define BMPMACRO to turn the definitions of the size of a bmp_t into
|
||||
* compile-time constants. This improves efficiency but makes the code
|
||||
* platform-specific.
|
||||
*/
|
||||
|
||||
/* #define BMPMACRO 1 */
|
||||
|
||||
/* Some enterprise users may wish to disable the -F switch to minimise CPU
|
||||
* usage. To do this, define the macro NOFORCE.
|
||||
*/
|
||||
|
||||
/* #define NOFORCE 1 */
|
||||
|
||||
/* Define PRESETS to compile CRC RevEng with the preset models from the
|
||||
* CRC Catalogue. This implies BMPMACRO and so makes the code platform-
|
||||
* specific.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PRESETS 1 //
|
||||
#endif
|
||||
|
||||
|
||||
/* Macros defining the size of a bmp_t.
|
||||
* Their values only matter if PRESETS and/or BMPMACRO are defined, in
|
||||
* which case edit the macros below to suit your architecture.
|
||||
* Otherwise, BMP_BIT and BMP_SUB will be redefined as aliases of bmpbit
|
||||
* and bmpsub, global objects initialised at run time.
|
||||
*/
|
||||
|
||||
/* Size in bits of a bmp_t. Not necessarily a power of two. */
|
||||
|
||||
#define BMP_BIT 32
|
||||
|
||||
/* The highest power of two that is strictly less than BMP_BIT.
|
||||
* Initialises the index of a binary search for set bits in a bmp_t.
|
||||
*/
|
||||
|
||||
#define BMP_SUB 16
|
||||
|
||||
/*****************************************
|
||||
* *
|
||||
* End of user configuration options *
|
||||
* *
|
||||
*****************************************/
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
@@ -0,0 +1,81 @@
|
||||
/*----------------------------------------------------------------------
|
||||
|
||||
Replacement for Unix "getopt()", for DOS/Windows/etc.
|
||||
|
||||
getopt.c 1.3 2003/09/17 16:17:59
|
||||
|
||||
Copyright (C) 1998, 2003 by David A. Hinds -- All Rights Reserved
|
||||
|
||||
This file is part of ASPEX.
|
||||
|
||||
ASPEX is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ASPEX is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ASPEX; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "getopt.h"
|
||||
|
||||
char *optarg;
|
||||
int optind = 1, opterr, optopt;
|
||||
int pos = 0;
|
||||
int getopt(int argc, char *argv[], const char *optstring)
|
||||
{
|
||||
//static int pos = 0;
|
||||
char *str;
|
||||
|
||||
if (pos == 0) {
|
||||
if ((optind >= argc) || (*argv[optind] != '-'))
|
||||
return EOF;
|
||||
pos = 1;
|
||||
if (argv[optind][pos] == '\0')
|
||||
return EOF;
|
||||
}
|
||||
|
||||
str = strchr(optstring, argv[optind][pos]);
|
||||
if (str == NULL) {
|
||||
optopt = argv[optind][pos];
|
||||
if (opterr)
|
||||
fprintf(stderr, "%s: illegal option -- %c\n", argv[0],
|
||||
optopt);
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (str[1] == ':') {
|
||||
if (argv[optind][pos+1] != '\0') {
|
||||
optarg = &argv[optind][pos+1];
|
||||
return *str;
|
||||
}
|
||||
optind++;
|
||||
if (optind >= argc) {
|
||||
optopt = *str;
|
||||
if (opterr)
|
||||
fprintf(stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], optopt);
|
||||
return '?';
|
||||
}
|
||||
optarg = argv[optind];
|
||||
optind++; pos = 0;
|
||||
return *str;
|
||||
}
|
||||
else {
|
||||
pos++;
|
||||
if (argv[optind][pos] == '\0') {
|
||||
optind++;
|
||||
pos = 0;
|
||||
}
|
||||
return *str;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
getopt.h 1.2 2003/09/17 16:17:59
|
||||
|
||||
Copyright (C) 1998, 2003 by David A. Hinds -- All Rights Reserved
|
||||
|
||||
This file is part of ASPEX.
|
||||
|
||||
ASPEX is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ASPEX is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ASPEX; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt, pos;
|
||||
int getopt(int argc, char *argv[], const char *optstring);
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,488 @@
|
||||
/* reveng.c
|
||||
* Greg Cook, 9/Apr/2015
|
||||
*/
|
||||
|
||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
||||
*
|
||||
* This file is part of CRC RevEng.
|
||||
*
|
||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CRC RevEng is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* 2013-09-16: calini(), calout() work on shortest argument
|
||||
* 2013-06-11: added sequence number to uprog() calls
|
||||
* 2013-02-08: added polynomial range search
|
||||
* 2013-01-18: refactored model checking to pshres(); renamed chkres()
|
||||
* 2012-05-24: efficiently build Init contribution string
|
||||
* 2012-05-24: removed broken search for crossed-endian algorithms
|
||||
* 2012-05-23: rewrote engini() after Ewing; removed modini()
|
||||
* 2011-01-17: fixed ANSI C warnings
|
||||
* 2011-01-08: fixed calini(), modini() caters for crossed-endian algos
|
||||
* 2011-01-04: renamed functions, added calini(), factored pshres();
|
||||
* rewrote engini() and implemented quick Init search
|
||||
* 2011-01-01: reveng() initialises terminating entry, addparms()
|
||||
* initialises all fields
|
||||
* 2010-12-26: renamed CRC RevEng. right results, rejects polys faster
|
||||
* 2010-12-24: completed, first tests (unsuccessful)
|
||||
* 2010-12-21: completed modulate(), partial sketch of reveng()
|
||||
* 2010-12-19: started reveng
|
||||
*/
|
||||
|
||||
/* reveng() can in theory be modified to search for polynomials shorter
|
||||
* than the full width as well, but this imposes a heavy time burden on
|
||||
* the full width search, which is the primary use case, as well as
|
||||
* complicating the search range function introduced in version 1.1.0.
|
||||
* It is more effective to search for each shorter width directly.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FILE void
|
||||
#include "reveng.h"
|
||||
|
||||
static poly_t *modpol(const poly_t init, int rflags, int args, const poly_t *argpolys);
|
||||
static void engini(int *resc, model_t **result, const poly_t divisor, int flags, int args, const poly_t *argpolys);
|
||||
static void calout(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, int args, const poly_t *argpolys);
|
||||
static void calini(int *resc, model_t **result, const poly_t divisor, int flags, const poly_t xorout, int args, const poly_t *argpolys);
|
||||
static void chkres(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, const poly_t xorout, int args, const poly_t *argpolys);
|
||||
|
||||
static const poly_t pzero = PZERO;
|
||||
|
||||
model_t *
|
||||
reveng(const model_t *guess, const poly_t qpoly, int rflags, int args, const poly_t *argpolys) {
|
||||
/* Complete the parameters of a model by calculation or brute search. */
|
||||
poly_t *pworks, *wptr, rem, gpoly;
|
||||
model_t *result = NULL, *rptr;
|
||||
int resc = 0;
|
||||
unsigned long spin = 0, seq = 0;
|
||||
|
||||
if(~rflags & R_HAVEP) {
|
||||
/* The poly is not known.
|
||||
* Produce a list of differences between the arguments.
|
||||
*/
|
||||
pworks = modpol(guess->init, rflags, args, argpolys);
|
||||
if(!pworks || !plen(*pworks)) {
|
||||
free(pworks);
|
||||
goto requit;
|
||||
}
|
||||
/* Initialise the guessed poly to the starting value. */
|
||||
gpoly = pclone(guess->spoly);
|
||||
/* Clear the least significant term, to be set in the
|
||||
* loop. qpoly does not need fixing as it is only
|
||||
* compared with odd polys.
|
||||
*/
|
||||
if(plen(gpoly))
|
||||
pshift(&gpoly, gpoly, 0UL, 0UL, plen(gpoly) - 1UL, 1UL);
|
||||
|
||||
while(piter(&gpoly) && (~rflags & R_HAVEQ || pcmp(&gpoly, &qpoly) < 0)) {
|
||||
/* For each possible poly of this size, try
|
||||
* dividing all the differences in the list.
|
||||
*/
|
||||
if(!(spin++ & R_SPMASK)) {
|
||||
uprog(gpoly, guess->flags, seq++);
|
||||
}
|
||||
for(wptr = pworks; plen(*wptr); ++wptr) {
|
||||
/* straight divide message by poly, don't multiply by x^n */
|
||||
rem = pcrc(*wptr, gpoly, pzero, pzero, 0);
|
||||
if(ptst(rem)) {
|
||||
pfree(&rem);
|
||||
break;
|
||||
} else
|
||||
pfree(&rem);
|
||||
}
|
||||
/* If gpoly divides all the differences, it is a
|
||||
* candidate. Search for an Init value for this
|
||||
* poly or if Init is known, log the result.
|
||||
*/
|
||||
if(!plen(*wptr)) {
|
||||
/* gpoly is a candidate poly */
|
||||
if(rflags & R_HAVEI && rflags & R_HAVEX)
|
||||
chkres(&resc, &result, gpoly, guess->init, guess->flags, guess->xorout, args, argpolys);
|
||||
else if(rflags & R_HAVEI)
|
||||
calout(&resc, &result, gpoly, guess->init, guess->flags, args, argpolys);
|
||||
else if(rflags & R_HAVEX)
|
||||
calini(&resc, &result, gpoly, guess->flags, guess->xorout, args, argpolys);
|
||||
else
|
||||
engini(&resc, &result, gpoly, guess->flags, args, argpolys);
|
||||
}
|
||||
if(!piter(&gpoly))
|
||||
break;
|
||||
}
|
||||
/* Finished with gpoly and the differences list, free them.
|
||||
*/
|
||||
pfree(&gpoly);
|
||||
for(wptr = pworks; plen(*wptr); ++wptr)
|
||||
pfree(wptr);
|
||||
free(pworks);
|
||||
}
|
||||
else if(rflags & R_HAVEI && rflags & R_HAVEX)
|
||||
/* All parameters are known! Submit the result if we get here */
|
||||
chkres(&resc, &result, guess->spoly, guess->init, guess->flags, guess->xorout, args, argpolys);
|
||||
else if(rflags & R_HAVEI)
|
||||
/* Poly and Init are known, calculate XorOut */
|
||||
calout(&resc, &result, guess->spoly, guess->init, guess->flags, args, argpolys);
|
||||
else if(rflags & R_HAVEX)
|
||||
/* Poly and XorOut are known, calculate Init */
|
||||
calini(&resc, &result, guess->spoly, guess->flags, guess->xorout, args, argpolys);
|
||||
else
|
||||
/* Poly is known but not Init; search for Init. */
|
||||
engini(&resc, &result, guess->spoly, guess->flags, args, argpolys);
|
||||
|
||||
requit:
|
||||
if(!(result = realloc(result, ++resc * sizeof(model_t))))
|
||||
uerror("cannot reallocate result array");
|
||||
rptr = result + resc - 1;
|
||||
rptr->spoly = pzero;
|
||||
rptr->init = pzero;
|
||||
rptr->flags = 0;
|
||||
rptr->xorout = pzero;
|
||||
rptr->check = pzero;
|
||||
rptr->name = NULL;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static poly_t *
|
||||
modpol(const poly_t init, int rflags, int args, const poly_t *argpolys) {
|
||||
/* Produce, in ascending length order, a list of differences
|
||||
* between the arguments in the list by summing pairs of arguments.
|
||||
* If R_HAVEI is not set in rflags, only pairs of equal length are
|
||||
* summed.
|
||||
* Otherwise, sums of right-aligned pairs are also returned, with
|
||||
* the supplied init poly added to the leftmost terms of each
|
||||
* poly of the pair.
|
||||
*/
|
||||
poly_t work, swap, *result, *rptr, *iptr;
|
||||
const poly_t *aptr, *bptr, *eptr = argpolys + args;
|
||||
unsigned long alen, blen;
|
||||
|
||||
if(args < 2) return(NULL);
|
||||
|
||||
if(!(result = malloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t))))
|
||||
uerror("cannot allocate memory for codeword table");
|
||||
|
||||
rptr = result;
|
||||
|
||||
for(aptr = argpolys; aptr < eptr; ++aptr) {
|
||||
alen = plen(*aptr);
|
||||
for(bptr = aptr + 1; bptr < eptr; ++bptr) {
|
||||
blen = plen(*bptr);
|
||||
if(alen == blen) {
|
||||
work = pclone(*aptr);
|
||||
psum(&work, *bptr, 0UL);
|
||||
} else if(rflags & R_HAVEI && alen < blen) {
|
||||
work = pclone(*bptr);
|
||||
psum(&work, *aptr, blen - alen);
|
||||
psum(&work, init, 0UL);
|
||||
psum(&work, init, blen - alen);
|
||||
} else if(rflags & R_HAVEI /* && alen > blen */) {
|
||||
work = pclone(*aptr);
|
||||
psum(&work, *bptr, alen - blen);
|
||||
psum(&work, init, 0UL);
|
||||
psum(&work, init, alen - blen);
|
||||
} else
|
||||
work = pzero;
|
||||
|
||||
if(plen(work))
|
||||
pnorm(&work);
|
||||
if((blen = plen(work))) {
|
||||
/* insert work into result[] in ascending order of length */
|
||||
for(iptr = result; iptr < rptr; ++iptr) {
|
||||
if(plen(work) < plen(*iptr)) {
|
||||
swap = *iptr;
|
||||
*iptr = work;
|
||||
work = swap;
|
||||
}
|
||||
else if(plen(*iptr) == blen && !pcmp(&work, iptr)) {
|
||||
pfree(&work);
|
||||
work = *--rptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*rptr++ = work;
|
||||
}
|
||||
}
|
||||
}
|
||||
*rptr = pzero;
|
||||
return(result);
|
||||
}
|
||||
|
||||
static void
|
||||
engini(int *resc, model_t **result, const poly_t divisor, int flags, int args, const poly_t *argpolys) {
|
||||
/* Search for init values implied by the arguments.
|
||||
* Method from: Ewing, Gregory C. (March 2010).
|
||||
* "Reverse-Engineering a CRC Algorithm". Christchurch:
|
||||
* University of Canterbury.
|
||||
* <http://www.cosc.canterbury.ac.nz/greg.ewing/essays/
|
||||
* CRC-Reverse-Engineering.html>
|
||||
*/
|
||||
poly_t apoly = PZERO, bpoly, pone = PZERO, *mat, *jptr;
|
||||
const poly_t *aptr, *bptr, *iptr;
|
||||
unsigned long alen, blen, dlen, ilen, i, j;
|
||||
int cy;
|
||||
|
||||
dlen = plen(divisor);
|
||||
|
||||
/* Allocate the CRC matrix */
|
||||
if(!(mat = (poly_t *) malloc((dlen << 1) * sizeof(poly_t))))
|
||||
uerror("cannot allocate memory for CRC matrix");
|
||||
|
||||
/* Find arguments of the two shortest lengths */
|
||||
alen = blen = plen(*(aptr = bptr = iptr = argpolys));
|
||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
||||
ilen = plen(*iptr);
|
||||
if(ilen < alen) {
|
||||
bptr = aptr; blen = alen;
|
||||
aptr = iptr; alen = ilen;
|
||||
} else if(ilen > alen && (aptr == bptr || ilen < blen)) {
|
||||
bptr = iptr; blen = ilen;
|
||||
}
|
||||
}
|
||||
if(aptr == bptr) {
|
||||
/* if no arguments are suitable, calculate Init with an
|
||||
* assumed XorOut of 0. Create a padded XorOut
|
||||
*/
|
||||
palloc(&apoly, dlen);
|
||||
calini(resc, result, divisor, flags, apoly, args, argpolys);
|
||||
pfree(&apoly);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the potential contribution of the bottom bit of Init */
|
||||
palloc(&pone, 1UL);
|
||||
piter(&pone);
|
||||
if(blen < (dlen << 1)) {
|
||||
palloc(&apoly, dlen); /* >= 1 */
|
||||
psum(&apoly, pone, (dlen << 1) - 1UL - blen); /* >= 0 */
|
||||
psum(&apoly, pone, (dlen << 1) - 1UL - alen); /* >= 1 */
|
||||
} else {
|
||||
palloc(&apoly, blen - dlen + 1UL); /* > dlen */
|
||||
psum(&apoly, pone, 0UL);
|
||||
psum(&apoly, pone, blen - alen); /* >= 1 */
|
||||
}
|
||||
if(plen(apoly) > dlen) {
|
||||
mat[dlen] = pcrc(apoly, divisor, pzero, pzero, 0);
|
||||
pfree(&apoly);
|
||||
} else {
|
||||
mat[dlen] = apoly;
|
||||
}
|
||||
|
||||
/* Find the actual contribution of Init */
|
||||
apoly = pcrc(*aptr, divisor, pzero, pzero, 0);
|
||||
bpoly = pcrc(*bptr, divisor, pzero, apoly, 0);
|
||||
|
||||
/* Populate the matrix */
|
||||
palloc(&apoly, 1UL);
|
||||
for(jptr=mat; jptr<mat+dlen; ++jptr)
|
||||
*jptr = pzero;
|
||||
for(iptr = jptr++; jptr < mat + (dlen << 1); iptr = jptr++)
|
||||
*jptr = pcrc(apoly, divisor, *iptr, pzero, P_MULXN);
|
||||
pfree(&apoly);
|
||||
|
||||
/* Transpose the matrix, augment with the Init contribution
|
||||
* and convert to row echelon form
|
||||
*/
|
||||
for(i=0UL; i<dlen; ++i) {
|
||||
apoly = pzero;
|
||||
iptr = mat + (dlen << 1);
|
||||
for(j=0UL; j<dlen; ++j)
|
||||
ppaste(&apoly, *--iptr, i, j, j + 1UL, dlen + 1UL);
|
||||
if(ptst(apoly))
|
||||
ppaste(&apoly, bpoly, i, dlen, dlen + 1UL, dlen + 1UL);
|
||||
j = pfirst(apoly);
|
||||
while(j < dlen && !pident(mat[j], pzero)) {
|
||||
psum(&apoly, mat[j], 0UL); /* pfirst(apoly) > j */
|
||||
j = pfirst(apoly);
|
||||
}
|
||||
if(j < dlen)
|
||||
mat[j] = apoly; /* pident(mat[j], pzero) || pfirst(mat[j]) == j */
|
||||
else
|
||||
pfree(&apoly);
|
||||
}
|
||||
palloc(&bpoly, dlen + 1UL);
|
||||
psum(&bpoly, pone, dlen);
|
||||
|
||||
/* Iterate through all solutions */
|
||||
do {
|
||||
/* Solve the matrix by Gaussian elimination.
|
||||
* The parity of the result, masked by each row, should be even.
|
||||
*/
|
||||
cy = 1;
|
||||
apoly = pclone(bpoly);
|
||||
jptr = mat + dlen;
|
||||
for(i=0UL; i<dlen; ++i) {
|
||||
/* Compute next bit of Init */
|
||||
if(pmpar(apoly, *--jptr))
|
||||
psum(&apoly, pone, dlen - 1UL - i);
|
||||
/* Toggle each zero row with carry, for next iteration */
|
||||
if(cy) {
|
||||
if(pident(*jptr, pzero)) {
|
||||
/* 0 to 1, no carry */
|
||||
*jptr = bpoly;
|
||||
cy = 0;
|
||||
} else if(pident(*jptr, bpoly)) {
|
||||
/* 1 to 0, carry forward */
|
||||
*jptr = pzero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Trim the augment mask bit */
|
||||
praloc(&apoly, dlen);
|
||||
|
||||
/* Test the Init value and add to results if correct */
|
||||
calout(resc, result, divisor, apoly, flags, args, argpolys);
|
||||
pfree(&apoly);
|
||||
} while(!cy);
|
||||
pfree(&pone);
|
||||
pfree(&bpoly);
|
||||
|
||||
/* Free the matrix. */
|
||||
for(jptr=mat; jptr < mat + (dlen << 1); ++jptr)
|
||||
pfree(jptr);
|
||||
free(mat);
|
||||
}
|
||||
|
||||
static void
|
||||
calout(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, int args, const poly_t *argpolys) {
|
||||
/* Calculate Xorout, check it against all the arguments and
|
||||
* add to results if consistent.
|
||||
*/
|
||||
poly_t xorout;
|
||||
const poly_t *aptr, *iptr;
|
||||
unsigned long alen, ilen;
|
||||
|
||||
if(args < 1) return;
|
||||
|
||||
/* find argument of the shortest length */
|
||||
alen = plen(*(aptr = iptr = argpolys));
|
||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
||||
ilen = plen(*iptr);
|
||||
if(ilen < alen) {
|
||||
aptr = iptr; alen = ilen;
|
||||
}
|
||||
}
|
||||
|
||||
xorout = pcrc(*aptr, divisor, init, pzero, 0);
|
||||
/* On little-endian algorithms, the calculations yield
|
||||
* the reverse of the actual xorout: in the Williams
|
||||
* model, the refout stage intervenes between init and
|
||||
* xorout.
|
||||
*/
|
||||
if(flags & P_REFOUT)
|
||||
prev(&xorout);
|
||||
|
||||
/* Submit the model to the results table.
|
||||
* Could skip the shortest argument but we wish to check our
|
||||
* calculation.
|
||||
*/
|
||||
chkres(resc, result, divisor, init, flags, xorout, args, argpolys);
|
||||
pfree(&xorout);
|
||||
}
|
||||
|
||||
static void
|
||||
calini(int *resc, model_t **result, const poly_t divisor, int flags, const poly_t xorout, int args, const poly_t *argpolys) {
|
||||
/* Calculate Init, check it against all the arguments and add to
|
||||
* results if consistent.
|
||||
*/
|
||||
poly_t rcpdiv, rxor, arg, init;
|
||||
const poly_t *aptr, *iptr;
|
||||
unsigned long alen, ilen;
|
||||
|
||||
if(args < 1) return;
|
||||
|
||||
/* find argument of the shortest length */
|
||||
alen = plen(*(aptr = iptr = argpolys));
|
||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
||||
ilen = plen(*iptr);
|
||||
if(ilen < alen) {
|
||||
aptr = iptr; alen = ilen;
|
||||
}
|
||||
}
|
||||
|
||||
rcpdiv = pclone(divisor);
|
||||
prcp(&rcpdiv);
|
||||
/* If the algorithm is reflected, an ordinary CRC requires the
|
||||
* model's XorOut to be reversed, as XorOut follows the RefOut
|
||||
* stage. To reverse the CRC calculation we need rxor to be the
|
||||
* mirror image of the forward XorOut.
|
||||
*/
|
||||
rxor = pclone(xorout);
|
||||
if(~flags & P_REFOUT)
|
||||
prev(&rxor);
|
||||
arg = pclone(*aptr);
|
||||
prev(&arg);
|
||||
|
||||
init = pcrc(arg, rcpdiv, rxor, pzero, 0);
|
||||
pfree(&arg);
|
||||
pfree(&rxor);
|
||||
pfree(&rcpdiv);
|
||||
prev(&init);
|
||||
|
||||
/* Submit the model to the results table.
|
||||
* Could skip the shortest argument but we wish to check our
|
||||
* calculation.
|
||||
*/
|
||||
chkres(resc, result, divisor, init, flags, xorout, args, argpolys);
|
||||
pfree(&init);
|
||||
}
|
||||
|
||||
static void
|
||||
chkres(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, const poly_t xorout, int args, const poly_t *argpolys) {
|
||||
/* Checks a model against the argument list, and adds to the
|
||||
* external results table if consistent.
|
||||
* Extends the result array and update the external pointer if
|
||||
* necessary.
|
||||
*/
|
||||
model_t *rptr;
|
||||
poly_t xor, crc;
|
||||
const poly_t *aptr = argpolys, *const eptr = argpolys + args;
|
||||
|
||||
/* If the algorithm is reflected, an ordinary CRC requires the
|
||||
* model's XorOut to be reversed, as XorOut follows the RefOut
|
||||
* stage.
|
||||
*/
|
||||
xor = pclone(xorout);
|
||||
if(flags & P_REFOUT)
|
||||
prev(&xor);
|
||||
|
||||
for(; aptr < eptr; ++aptr) {
|
||||
crc = pcrc(*aptr, divisor, init, xor, 0);
|
||||
if(ptst(crc)) {
|
||||
pfree(&crc);
|
||||
break;
|
||||
} else {
|
||||
pfree(&crc);
|
||||
}
|
||||
}
|
||||
pfree(&xor);
|
||||
if(aptr != eptr) return;
|
||||
|
||||
if(!(*result = realloc(*result, ++*resc * sizeof(model_t))))
|
||||
uerror("cannot reallocate result array");
|
||||
|
||||
rptr = *result + *resc - 1;
|
||||
rptr->spoly = pclone(divisor);
|
||||
rptr->init = pclone(init);
|
||||
rptr->flags = flags;
|
||||
rptr->xorout = pclone(xorout);
|
||||
rptr->name = NULL;
|
||||
|
||||
/* compute check value for this model */
|
||||
mcheck(rptr);
|
||||
|
||||
/* callback to notify new model */
|
||||
ufound(rptr);
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/* reveng.h
|
||||
* Greg Cook, 9/Apr/2015
|
||||
*/
|
||||
|
||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
||||
*
|
||||
* This file is part of CRC RevEng.
|
||||
*
|
||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CRC RevEng is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REVENG_H
|
||||
#define REVENG_H 1
|
||||
|
||||
/* Configuration options */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef BMP_T
|
||||
# error config.h: BMP_T must be defined as unsigned long or a longer unsigned type
|
||||
#endif
|
||||
|
||||
#ifndef BMP_C
|
||||
# error config.h: BMP_C() must define a BMP_T constant
|
||||
#endif
|
||||
|
||||
#if !defined PRESETS && !defined BMPMACRO
|
||||
# undef BMP_BIT
|
||||
# undef BMP_SUB
|
||||
#endif
|
||||
|
||||
#undef BMP_POF2
|
||||
|
||||
#ifdef BMP_BIT
|
||||
# ifndef BMP_SUB
|
||||
# error config.h: BMP_SUB must be defined as the highest power of two that is strictly less than BMP_BIT
|
||||
# elif BMP_BIT < 32
|
||||
# error config.h: BMP_BIT must be at least 32
|
||||
# elif BMP_SUB < 16
|
||||
# error config.h: BMP_SUB must be at least 16
|
||||
# elif (BMP_SUB >= BMP_BIT || BMP_SUB << 1 < BMP_BIT || BMP_SUB & (BMP_SUB - 1))
|
||||
# error config.h: BMP_SUB must be defined as the highest power of two that is strictly less than BMP_BIT
|
||||
# else /* BMP_SUB */
|
||||
# define SETBMP()
|
||||
# endif /* BMP_SUB */
|
||||
# if BMP_BIT == 32
|
||||
# define BMP_POF2 5
|
||||
# elif BMP_BIT == 64
|
||||
# define BMP_POF2 6
|
||||
# elif BMP_BIT == 128
|
||||
# define BMP_POF2 7
|
||||
# elif BMP_BIT == 256
|
||||
# define BMP_POF2 8
|
||||
# elif BMP_BIT == 512
|
||||
# define BMP_POF2 9
|
||||
# elif BMP_BIT == 1024
|
||||
# define BMP_POF2 10
|
||||
# elif BMP_BIT == 2048
|
||||
# define BMP_POF2 11
|
||||
# elif BMP_BIT == 4096
|
||||
# define BMP_POF2 12
|
||||
# elif BMP_BIT == 8192
|
||||
# define BMP_POF2 13
|
||||
# elif BMP_BIT == 16384
|
||||
# define BMP_POF2 14
|
||||
# elif BMP_BIT == 32768
|
||||
# define BMP_POF2 15
|
||||
# elif BMP_BIT == 65536
|
||||
# define BMP_POF2 16
|
||||
/* may extend list as required */
|
||||
# elif (BMP_BIT & (BMP_BIT - 1)) == 0
|
||||
# define BMP_POF2 1
|
||||
# endif
|
||||
#else /* BMP_BIT */
|
||||
# define BMP_BIT bmpbit
|
||||
# define BMP_SUB bmpsub
|
||||
# define SETBMP() setbmp()
|
||||
#endif /* BMP_BIT */
|
||||
|
||||
/* Global definitions */
|
||||
|
||||
/* CRC RevEng version string */
|
||||
#define VERSION "1.3.0"
|
||||
|
||||
/* bmpbit.c */
|
||||
typedef BMP_T bmp_t;
|
||||
|
||||
extern int bmpbit, bmpsub;
|
||||
extern void setbmp(void);
|
||||
|
||||
/* poly.c */
|
||||
#define P_REFIN 1
|
||||
#define P_REFOUT 2
|
||||
#define P_MULXN 4
|
||||
#define P_RTJUST 8
|
||||
#define P_UPPER 16
|
||||
#define P_SPACE 32
|
||||
#define P_LTLBYT 64
|
||||
#define P_DIRECT 128
|
||||
|
||||
/* default flags */
|
||||
#define P_BE (P_RTJUST | P_MULXN)
|
||||
#define P_LE (P_REFIN | P_REFOUT | P_MULXN)
|
||||
#define P_BELE (P_REFOUT | P_MULXN)
|
||||
#define P_LEBE (P_REFIN | P_RTJUST | P_MULXN)
|
||||
|
||||
/* A poly_t constant representing the polynomial 0. */
|
||||
#define PZERO {0UL, (bmp_t *) 0}
|
||||
|
||||
typedef struct {
|
||||
unsigned long length; /* number of significant bits */
|
||||
bmp_t *bitmap; /* bitmap, MSB first, */
|
||||
/* left-justified in each word */
|
||||
} poly_t;
|
||||
|
||||
extern poly_t filtop(FILE *input, unsigned long length, int flags, int bperhx);
|
||||
extern poly_t strtop(const char *string, int flags, int bperhx);
|
||||
extern char *ptostr(const poly_t poly, int flags, int bperhx);
|
||||
extern char *pxsubs(const poly_t poly, int flags, int bperhx, unsigned long start, unsigned long end);
|
||||
extern poly_t pclone(const poly_t poly);
|
||||
extern void pcpy(poly_t *dest, const poly_t src);
|
||||
extern void pcanon(poly_t *poly);
|
||||
extern void pnorm(poly_t *poly);
|
||||
extern void psnorm(poly_t *poly);
|
||||
extern void pchop(poly_t *poly);
|
||||
extern void pkchop(poly_t *poly);
|
||||
extern unsigned long plen(const poly_t poly);
|
||||
extern int pcmp(const poly_t *a, const poly_t *b);
|
||||
extern int psncmp(const poly_t *a, const poly_t *b);
|
||||
extern int ptst(const poly_t poly);
|
||||
extern unsigned long pfirst(const poly_t poly);
|
||||
extern unsigned long plast(const poly_t poly);
|
||||
extern poly_t psubs(const poly_t src, unsigned long head, unsigned long start, unsigned long end, unsigned long tail);
|
||||
extern void pright(poly_t *poly, unsigned long length);
|
||||
extern void pshift(poly_t *dest, const poly_t src, unsigned long head, unsigned long start, unsigned long end, unsigned long tail);
|
||||
extern void ppaste(poly_t *dest, const poly_t src, unsigned long skip, unsigned long seek, unsigned long end, unsigned long fulllength);
|
||||
extern void pdiff(poly_t *dest, const poly_t src, unsigned long ofs);
|
||||
extern void psum(poly_t *dest, const poly_t src, unsigned long ofs);
|
||||
extern void prev(poly_t *poly);
|
||||
extern void prevch(poly_t *poly, int bperhx);
|
||||
extern void prcp(poly_t *poly);
|
||||
extern void pinv(poly_t *poly);
|
||||
extern poly_t pmod(const poly_t dividend, const poly_t divisor);
|
||||
extern poly_t pcrc(const poly_t message, const poly_t divisor, const poly_t init, const poly_t xorout, int flags);
|
||||
extern int piter(poly_t *poly);
|
||||
extern void palloc(poly_t *poly, unsigned long length);
|
||||
extern void pfree(poly_t *poly);
|
||||
extern void praloc(poly_t *poly, unsigned long length);
|
||||
extern int pmpar(const poly_t poly, const poly_t mask);
|
||||
extern int pident(const poly_t a, const poly_t b);
|
||||
|
||||
/* model.c */
|
||||
#define M_OVERWR 256
|
||||
|
||||
typedef struct {
|
||||
poly_t spoly; /* polynomial with highest-order term removed. length determines CRC width */
|
||||
poly_t init; /* initial register value. length == poly.length */
|
||||
int flags; /* P_REFIN and P_REFOUT indicate reflected input/output */
|
||||
poly_t xorout; /* final register XOR mask. length == poly.length */
|
||||
poly_t check; /* optional check value, the CRC of the UTF-8 string "123456789" */
|
||||
const char *name; /* optional canonical name of the model */
|
||||
} model_t;
|
||||
|
||||
extern void mcpy(model_t *dest, const model_t *src);
|
||||
extern void mfree(model_t *model);
|
||||
extern int mcmp(const model_t *a, const model_t *b);
|
||||
extern int mbynam(model_t *dest, const char *key);
|
||||
extern void mbynum(model_t *dest, int num);
|
||||
extern int mcount(void);
|
||||
extern char *mnames(void);
|
||||
extern char *mtostr(const model_t *model);
|
||||
extern void mmatch(model_t *model, int flags);
|
||||
extern void mcanon(model_t *model);
|
||||
extern void mcheck(model_t *model);
|
||||
extern void mrev(model_t *model);
|
||||
extern void mnovel(model_t *model);
|
||||
|
||||
/* reveng.c */
|
||||
#define R_HAVEP 512
|
||||
#define R_HAVEI 1024
|
||||
#define R_HAVERI 2048
|
||||
#define R_HAVERO 4096
|
||||
#define R_HAVEX 8192
|
||||
#define R_HAVEQ 16384
|
||||
|
||||
#define R_SPMASK 0x7FFFFFFUL
|
||||
|
||||
extern model_t *reveng(const model_t *guess, const poly_t qpoly, int rflags, int args, const poly_t *argpolys);
|
||||
|
||||
/* cli.c */
|
||||
#define C_INFILE 1
|
||||
#define C_FORCE 2
|
||||
#define C_RESULT 4
|
||||
|
||||
#define BUFFER 32768
|
||||
|
||||
extern int reveng_main(int argc, char *argv[]);
|
||||
extern void ufound(const model_t *model);
|
||||
extern void uerror(const char *msg);
|
||||
extern void uprog(const poly_t gpoly, int flags, unsigned long seq);
|
||||
|
||||
#endif /* REVENG_H */
|
||||
+18
-5
@@ -7,7 +7,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "crc16.h"
|
||||
|
||||
#define CRC16_MASK_CCITT 0x1021
|
||||
|
||||
unsigned short update_crc16( unsigned short crc, unsigned char c )
|
||||
{
|
||||
@@ -41,9 +41,22 @@ uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t
|
||||
}
|
||||
|
||||
uint16_t crc16_ccitt(uint8_t const *message, int length) {
|
||||
return crc16(message, length, 0xffff, 0x1021);
|
||||
return crc16(message, length, 0xffff, CRC16_MASK_CCITT);
|
||||
}
|
||||
|
||||
uint16_t crc16_ccitt_rev(uint8_t const *message, int length) {
|
||||
return crc16(message, length, 0x0000, 0x1021);
|
||||
}
|
||||
uint16_t crc16_ccitt_kermit(uint8_t const *message, int length) {
|
||||
return bit_reverse_uint16(crc16(message, length, 0x0000, CRC16_MASK_CCITT));
|
||||
}
|
||||
uint16_t bit_reverse_uint16 (uint16_t value) {
|
||||
const uint16_t mask0 = 0x5555;
|
||||
const uint16_t mask1 = 0x3333;
|
||||
const uint16_t mask2 = 0x0F0F;
|
||||
const uint16_t mask3 = 0x00FF;
|
||||
|
||||
value = (((~mask0) & value) >> 1) | ((mask0 & value) << 1);
|
||||
value = (((~mask1) & value) >> 2) | ((mask1 & value) << 2);
|
||||
value = (((~mask2) & value) >> 4) | ((mask2 & value) << 4);
|
||||
value = (((~mask3) & value) >> 8) | ((mask3 & value) << 8);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
+2
-1
@@ -12,5 +12,6 @@
|
||||
unsigned short update_crc16(unsigned short crc, unsigned char c);
|
||||
uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial);
|
||||
uint16_t crc16_ccitt(uint8_t const *message, int length);
|
||||
uint16_t crc16_ccitt_rev(uint8_t const *message, int length);
|
||||
uint16_t crc16_ccitt_kermit(uint8_t const *message, int length);
|
||||
uint16_t bit_reverse_uint16 (uint16_t value);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user