style: Format source code and support grouping client
This commit is contained in:
587
common/aes.c
587
common/aes.c
@@ -19,10 +19,10 @@ ECB-AES128
|
||||
2b7e151628aed2a6abf7158809cf4f3c
|
||||
|
||||
resulting cipher
|
||||
3ad77bb40d7a3660a89ecaf32466ef97
|
||||
f5d3d58503b9699de785895a96fdbaaf
|
||||
43b1cd7f598ece23881b00e3ed030688
|
||||
7b0c785e27e8ad3f8223207104725dd4
|
||||
3ad77bb40d7a3660a89ecaf32466ef97
|
||||
f5d3d58503b9699de785895a96fdbaaf
|
||||
43b1cd7f598ece23881b00e3ed030688
|
||||
7b0c785e27e8ad3f8223207104725dd4
|
||||
|
||||
|
||||
NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
|
||||
@@ -44,21 +44,21 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
|
||||
#define Nb 4
|
||||
|
||||
#if defined(AES256) && (AES256 == 1)
|
||||
#define Nk 8
|
||||
#define Nr 14
|
||||
#define Nk 8
|
||||
#define Nr 14
|
||||
#elif defined(AES192) && (AES192 == 1)
|
||||
#define Nk 6
|
||||
#define Nr 12
|
||||
#define Nk 6
|
||||
#define Nr 12
|
||||
#else
|
||||
#define Nk 4 // The number of 32 bit words in a key.
|
||||
#define Nr 10 // The number of rounds in AES Cipher.
|
||||
#define Nk 4 // The number of 32 bit words in a key.
|
||||
#define Nr 10 // The number of rounds in AES Cipher.
|
||||
#endif
|
||||
|
||||
// jcallan@github points out that declaring Multiply as a function
|
||||
// jcallan@github points out that declaring Multiply as a function
|
||||
// reduces code size considerably with the Keil ARM compiler.
|
||||
// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
|
||||
#ifndef MULTIPLY_AS_A_FUNCTION
|
||||
#define MULTIPLY_AS_A_FUNCTION 0
|
||||
#define MULTIPLY_AS_A_FUNCTION 0
|
||||
#endif
|
||||
|
||||
|
||||
@@ -73,59 +73,62 @@ typedef uint8_t state_t[4][4];
|
||||
|
||||
|
||||
// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
|
||||
// The numbers below can be computed dynamically trading ROM for RAM -
|
||||
// The numbers below can be computed dynamically trading ROM for RAM -
|
||||
// This can be useful in (embedded) bootloader applications, where ROM is often limited.
|
||||
static const uint8_t sbox[256] = {
|
||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
|
||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
};
|
||||
|
||||
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
|
||||
static const uint8_t rsbox[256] = {
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
||||
};
|
||||
#endif
|
||||
|
||||
// The round constant word array, Rcon[i], contains the values given by
|
||||
// The round constant word array, Rcon[i], contains the values given by
|
||||
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
|
||||
static const uint8_t Rcon[11] = {
|
||||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
|
||||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
|
||||
};
|
||||
|
||||
/*
|
||||
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
|
||||
* that you can remove most of the elements in the Rcon array, because they are unused.
|
||||
*
|
||||
* From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
|
||||
*
|
||||
* "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed),
|
||||
*
|
||||
* "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed),
|
||||
* up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
|
||||
*/
|
||||
|
||||
@@ -141,93 +144,90 @@ static uint8_t getSBoxValue(uint8_t num)
|
||||
*/
|
||||
#define getSBoxValue(num) (sbox[(num)])
|
||||
|
||||
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
|
||||
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
|
||||
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
|
||||
{
|
||||
unsigned i, j, k;
|
||||
uint8_t tempa[4]; // Used for the column/row operations
|
||||
|
||||
// The first round key is the key itself.
|
||||
for (i = 0; i < Nk; ++i)
|
||||
{
|
||||
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
|
||||
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
|
||||
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
|
||||
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
|
||||
}
|
||||
|
||||
// All other round keys are found from the previous round keys.
|
||||
for (i = Nk; i < Nb * (Nr + 1); ++i)
|
||||
{
|
||||
{
|
||||
k = (i - 1) * 4;
|
||||
tempa[0]=RoundKey[k + 0];
|
||||
tempa[1]=RoundKey[k + 1];
|
||||
tempa[2]=RoundKey[k + 2];
|
||||
tempa[3]=RoundKey[k + 3];
|
||||
unsigned i, j, k;
|
||||
uint8_t tempa[4]; // Used for the column/row operations
|
||||
|
||||
// The first round key is the key itself.
|
||||
for (i = 0; i < Nk; ++i) {
|
||||
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
|
||||
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
|
||||
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
|
||||
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
|
||||
}
|
||||
|
||||
if (i % Nk == 0)
|
||||
{
|
||||
// This function shifts the 4 bytes in a word to the left once.
|
||||
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
|
||||
// All other round keys are found from the previous round keys.
|
||||
for (i = Nk; i < Nb * (Nr + 1); ++i) {
|
||||
{
|
||||
k = (i - 1) * 4;
|
||||
tempa[0]=RoundKey[k + 0];
|
||||
tempa[1]=RoundKey[k + 1];
|
||||
tempa[2]=RoundKey[k + 2];
|
||||
tempa[3]=RoundKey[k + 3];
|
||||
|
||||
// Function RotWord()
|
||||
{
|
||||
const uint8_t u8tmp = tempa[0];
|
||||
tempa[0] = tempa[1];
|
||||
tempa[1] = tempa[2];
|
||||
tempa[2] = tempa[3];
|
||||
tempa[3] = u8tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// SubWord() is a function that takes a four-byte input word and
|
||||
// applies the S-box to each of the four bytes to produce an output word.
|
||||
if (i % Nk == 0) {
|
||||
// This function shifts the 4 bytes in a word to the left once.
|
||||
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
|
||||
|
||||
// Function Subword()
|
||||
{
|
||||
tempa[0] = getSBoxValue(tempa[0]);
|
||||
tempa[1] = getSBoxValue(tempa[1]);
|
||||
tempa[2] = getSBoxValue(tempa[2]);
|
||||
tempa[3] = getSBoxValue(tempa[3]);
|
||||
}
|
||||
// Function RotWord()
|
||||
{
|
||||
const uint8_t u8tmp = tempa[0];
|
||||
tempa[0] = tempa[1];
|
||||
tempa[1] = tempa[2];
|
||||
tempa[2] = tempa[3];
|
||||
tempa[3] = u8tmp;
|
||||
}
|
||||
|
||||
tempa[0] = tempa[0] ^ Rcon[i/Nk];
|
||||
}
|
||||
// SubWord() is a function that takes a four-byte input word and
|
||||
// applies the S-box to each of the four bytes to produce an output word.
|
||||
|
||||
// Function Subword()
|
||||
{
|
||||
tempa[0] = getSBoxValue(tempa[0]);
|
||||
tempa[1] = getSBoxValue(tempa[1]);
|
||||
tempa[2] = getSBoxValue(tempa[2]);
|
||||
tempa[3] = getSBoxValue(tempa[3]);
|
||||
}
|
||||
|
||||
tempa[0] = tempa[0] ^ Rcon[i/Nk];
|
||||
}
|
||||
#if defined(AES256) && (AES256 == 1)
|
||||
if (i % Nk == 4)
|
||||
{
|
||||
// Function Subword()
|
||||
{
|
||||
tempa[0] = getSBoxValue(tempa[0]);
|
||||
tempa[1] = getSBoxValue(tempa[1]);
|
||||
tempa[2] = getSBoxValue(tempa[2]);
|
||||
tempa[3] = getSBoxValue(tempa[3]);
|
||||
}
|
||||
}
|
||||
if (i % Nk == 4) {
|
||||
// Function Subword()
|
||||
{
|
||||
tempa[0] = getSBoxValue(tempa[0]);
|
||||
tempa[1] = getSBoxValue(tempa[1]);
|
||||
tempa[2] = getSBoxValue(tempa[2]);
|
||||
tempa[3] = getSBoxValue(tempa[3]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
j = i * 4; k=(i - Nk) * 4;
|
||||
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
|
||||
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
|
||||
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
|
||||
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
|
||||
}
|
||||
j = i * 4;
|
||||
k=(i - Nk) * 4;
|
||||
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
|
||||
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
|
||||
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
|
||||
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
|
||||
}
|
||||
}
|
||||
|
||||
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
|
||||
{
|
||||
KeyExpansion(ctx->RoundKey, key);
|
||||
KeyExpansion(ctx->RoundKey, key);
|
||||
}
|
||||
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
|
||||
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
|
||||
{
|
||||
KeyExpansion(ctx->RoundKey, key);
|
||||
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
|
||||
KeyExpansion(ctx->RoundKey, key);
|
||||
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
|
||||
}
|
||||
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
|
||||
{
|
||||
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
|
||||
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -235,28 +235,24 @@ void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
|
||||
// The round key is added to the state by an XOR function.
|
||||
static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
|
||||
{
|
||||
uint8_t i,j;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
(*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
|
||||
uint8_t i,j;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (j = 0; j < 4; ++j) {
|
||||
(*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The SubBytes Function Substitutes the values in the
|
||||
// state matrix with values in an S-box.
|
||||
static void SubBytes(state_t* state)
|
||||
{
|
||||
uint8_t i, j;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
(*state)[j][i] = getSBoxValue((*state)[j][i]);
|
||||
uint8_t i, j;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (j = 0; j < 4; ++j) {
|
||||
(*state)[j][i] = getSBoxValue((*state)[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The ShiftRows() function shifts the rows in the state to the left.
|
||||
@@ -264,51 +260,58 @@ static void SubBytes(state_t* state)
|
||||
// Offset = Row number. So the first row is not shifted.
|
||||
static void ShiftRows(state_t* state)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
// Rotate first row 1 columns to left
|
||||
temp = (*state)[0][1];
|
||||
(*state)[0][1] = (*state)[1][1];
|
||||
(*state)[1][1] = (*state)[2][1];
|
||||
(*state)[2][1] = (*state)[3][1];
|
||||
(*state)[3][1] = temp;
|
||||
// Rotate first row 1 columns to left
|
||||
temp = (*state)[0][1];
|
||||
(*state)[0][1] = (*state)[1][1];
|
||||
(*state)[1][1] = (*state)[2][1];
|
||||
(*state)[2][1] = (*state)[3][1];
|
||||
(*state)[3][1] = temp;
|
||||
|
||||
// Rotate second row 2 columns to left
|
||||
temp = (*state)[0][2];
|
||||
(*state)[0][2] = (*state)[2][2];
|
||||
(*state)[2][2] = temp;
|
||||
// Rotate second row 2 columns to left
|
||||
temp = (*state)[0][2];
|
||||
(*state)[0][2] = (*state)[2][2];
|
||||
(*state)[2][2] = temp;
|
||||
|
||||
temp = (*state)[1][2];
|
||||
(*state)[1][2] = (*state)[3][2];
|
||||
(*state)[3][2] = temp;
|
||||
temp = (*state)[1][2];
|
||||
(*state)[1][2] = (*state)[3][2];
|
||||
(*state)[3][2] = temp;
|
||||
|
||||
// Rotate third row 3 columns to left
|
||||
temp = (*state)[0][3];
|
||||
(*state)[0][3] = (*state)[3][3];
|
||||
(*state)[3][3] = (*state)[2][3];
|
||||
(*state)[2][3] = (*state)[1][3];
|
||||
(*state)[1][3] = temp;
|
||||
// Rotate third row 3 columns to left
|
||||
temp = (*state)[0][3];
|
||||
(*state)[0][3] = (*state)[3][3];
|
||||
(*state)[3][3] = (*state)[2][3];
|
||||
(*state)[2][3] = (*state)[1][3];
|
||||
(*state)[1][3] = temp;
|
||||
}
|
||||
|
||||
static uint8_t xtime(uint8_t x)
|
||||
{
|
||||
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
|
||||
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
|
||||
}
|
||||
|
||||
// MixColumns function mixes the columns of the state matrix
|
||||
static void MixColumns(state_t* state)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t Tmp, Tm, t;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
t = (*state)[i][0];
|
||||
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
|
||||
Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
|
||||
Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
|
||||
Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
|
||||
Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
|
||||
}
|
||||
uint8_t i;
|
||||
uint8_t Tmp, Tm, t;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
t = (*state)[i][0];
|
||||
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
|
||||
Tm = (*state)[i][0] ^ (*state)[i][1] ;
|
||||
Tm = xtime(Tm);
|
||||
(*state)[i][0] ^= Tm ^ Tmp ;
|
||||
Tm = (*state)[i][1] ^ (*state)[i][2] ;
|
||||
Tm = xtime(Tm);
|
||||
(*state)[i][1] ^= Tm ^ Tmp ;
|
||||
Tm = (*state)[i][2] ^ (*state)[i][3] ;
|
||||
Tm = xtime(Tm);
|
||||
(*state)[i][2] ^= Tm ^ Tmp ;
|
||||
Tm = (*state)[i][3] ^ t ;
|
||||
Tm = xtime(Tm);
|
||||
(*state)[i][3] ^= Tm ^ Tmp ;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply is used to multiply numbers in the field GF(2^8)
|
||||
@@ -318,12 +321,12 @@ static void MixColumns(state_t* state)
|
||||
#if MULTIPLY_AS_A_FUNCTION
|
||||
static uint8_t Multiply(uint8_t x, uint8_t y)
|
||||
{
|
||||
return (((y & 1) * x) ^
|
||||
((y>>1 & 1) * xtime(x)) ^
|
||||
((y>>2 & 1) * xtime(xtime(x))) ^
|
||||
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
|
||||
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
|
||||
}
|
||||
return (((y & 1) * x) ^
|
||||
((y>>1 & 1) * xtime(x)) ^
|
||||
((y>>2 & 1) * xtime(xtime(x))) ^
|
||||
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
|
||||
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
|
||||
}
|
||||
#else
|
||||
#define Multiply(x, y) \
|
||||
( ((y & 1) * x) ^ \
|
||||
@@ -348,20 +351,19 @@ static uint8_t getSBoxInvert(uint8_t num)
|
||||
// Please use the references to gain more information.
|
||||
static void InvMixColumns(state_t* state)
|
||||
{
|
||||
int i;
|
||||
uint8_t a, b, c, d;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
a = (*state)[i][0];
|
||||
b = (*state)[i][1];
|
||||
c = (*state)[i][2];
|
||||
d = (*state)[i][3];
|
||||
int i;
|
||||
uint8_t a, b, c, d;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
a = (*state)[i][0];
|
||||
b = (*state)[i][1];
|
||||
c = (*state)[i][2];
|
||||
d = (*state)[i][3];
|
||||
|
||||
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
|
||||
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
|
||||
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
|
||||
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
|
||||
}
|
||||
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
|
||||
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
|
||||
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
|
||||
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,93 +371,89 @@ static void InvMixColumns(state_t* state)
|
||||
// state matrix with values in an S-box.
|
||||
static void InvSubBytes(state_t* state)
|
||||
{
|
||||
uint8_t i, j;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
|
||||
uint8_t i, j;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (j = 0; j < 4; ++j) {
|
||||
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void InvShiftRows(state_t* state)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
// Rotate first row 1 columns to right
|
||||
temp = (*state)[3][1];
|
||||
(*state)[3][1] = (*state)[2][1];
|
||||
(*state)[2][1] = (*state)[1][1];
|
||||
(*state)[1][1] = (*state)[0][1];
|
||||
(*state)[0][1] = temp;
|
||||
// Rotate first row 1 columns to right
|
||||
temp = (*state)[3][1];
|
||||
(*state)[3][1] = (*state)[2][1];
|
||||
(*state)[2][1] = (*state)[1][1];
|
||||
(*state)[1][1] = (*state)[0][1];
|
||||
(*state)[0][1] = temp;
|
||||
|
||||
// Rotate second row 2 columns to right
|
||||
temp = (*state)[0][2];
|
||||
(*state)[0][2] = (*state)[2][2];
|
||||
(*state)[2][2] = temp;
|
||||
// Rotate second row 2 columns to right
|
||||
temp = (*state)[0][2];
|
||||
(*state)[0][2] = (*state)[2][2];
|
||||
(*state)[2][2] = temp;
|
||||
|
||||
temp = (*state)[1][2];
|
||||
(*state)[1][2] = (*state)[3][2];
|
||||
(*state)[3][2] = temp;
|
||||
temp = (*state)[1][2];
|
||||
(*state)[1][2] = (*state)[3][2];
|
||||
(*state)[3][2] = temp;
|
||||
|
||||
// Rotate third row 3 columns to right
|
||||
temp = (*state)[0][3];
|
||||
(*state)[0][3] = (*state)[1][3];
|
||||
(*state)[1][3] = (*state)[2][3];
|
||||
(*state)[2][3] = (*state)[3][3];
|
||||
(*state)[3][3] = temp;
|
||||
// Rotate third row 3 columns to right
|
||||
temp = (*state)[0][3];
|
||||
(*state)[0][3] = (*state)[1][3];
|
||||
(*state)[1][3] = (*state)[2][3];
|
||||
(*state)[2][3] = (*state)[3][3];
|
||||
(*state)[3][3] = temp;
|
||||
}
|
||||
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
|
||||
|
||||
// Cipher is the main function that encrypts the PlainText.
|
||||
static void Cipher(state_t* state, const uint8_t* RoundKey)
|
||||
{
|
||||
uint8_t round = 0;
|
||||
uint8_t round = 0;
|
||||
|
||||
// Add the First round key to the state before starting the rounds.
|
||||
AddRoundKey(0, state, RoundKey);
|
||||
// Add the First round key to the state before starting the rounds.
|
||||
AddRoundKey(0, state, RoundKey);
|
||||
|
||||
// There will be Nr rounds.
|
||||
// The first Nr-1 rounds are identical.
|
||||
// These Nr rounds are executed in the loop below.
|
||||
// Last one without MixColumns()
|
||||
for (round = 1; ; ++round)
|
||||
{
|
||||
SubBytes(state);
|
||||
ShiftRows(state);
|
||||
if (round == Nr) {
|
||||
break;
|
||||
// There will be Nr rounds.
|
||||
// The first Nr-1 rounds are identical.
|
||||
// These Nr rounds are executed in the loop below.
|
||||
// Last one without MixColumns()
|
||||
for (round = 1; ; ++round) {
|
||||
SubBytes(state);
|
||||
ShiftRows(state);
|
||||
if (round == Nr) {
|
||||
break;
|
||||
}
|
||||
MixColumns(state);
|
||||
AddRoundKey(round, state, RoundKey);
|
||||
}
|
||||
MixColumns(state);
|
||||
AddRoundKey(round, state, RoundKey);
|
||||
}
|
||||
// Add round key to last round
|
||||
AddRoundKey(Nr, state, RoundKey);
|
||||
// Add round key to last round
|
||||
AddRoundKey(Nr, state, RoundKey);
|
||||
}
|
||||
|
||||
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
|
||||
static void InvCipher(state_t* state, const uint8_t* RoundKey)
|
||||
{
|
||||
uint8_t round = 0;
|
||||
uint8_t round = 0;
|
||||
|
||||
// Add the First round key to the state before starting the rounds.
|
||||
AddRoundKey(Nr, state, RoundKey);
|
||||
// Add the First round key to the state before starting the rounds.
|
||||
AddRoundKey(Nr, state, RoundKey);
|
||||
|
||||
// There will be Nr rounds.
|
||||
// The first Nr-1 rounds are identical.
|
||||
// These Nr rounds are executed in the loop below.
|
||||
// Last one without InvMixColumn()
|
||||
for (round = (Nr - 1); ; --round)
|
||||
{
|
||||
InvShiftRows(state);
|
||||
InvSubBytes(state);
|
||||
AddRoundKey(round, state, RoundKey);
|
||||
if (round == 0) {
|
||||
break;
|
||||
// There will be Nr rounds.
|
||||
// The first Nr-1 rounds are identical.
|
||||
// These Nr rounds are executed in the loop below.
|
||||
// Last one without InvMixColumn()
|
||||
for (round = (Nr - 1); ; --round) {
|
||||
InvShiftRows(state);
|
||||
InvSubBytes(state);
|
||||
AddRoundKey(round, state, RoundKey);
|
||||
if (round == 0) {
|
||||
break;
|
||||
}
|
||||
InvMixColumns(state);
|
||||
}
|
||||
InvMixColumns(state);
|
||||
}
|
||||
|
||||
}
|
||||
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
|
||||
@@ -468,14 +466,14 @@ static void InvCipher(state_t* state, const uint8_t* RoundKey)
|
||||
|
||||
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
|
||||
{
|
||||
// The next function call encrypts the PlainText with the Key using AES algorithm.
|
||||
Cipher((state_t*)buf, ctx->RoundKey);
|
||||
// The next function call encrypts the PlainText with the Key using AES algorithm.
|
||||
Cipher((state_t*)buf, ctx->RoundKey);
|
||||
}
|
||||
|
||||
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
|
||||
{
|
||||
// The next function call decrypts the PlainText with the Key using AES algorithm.
|
||||
InvCipher((state_t*)buf, ctx->RoundKey);
|
||||
// The next function call decrypts the PlainText with the Key using AES algorithm.
|
||||
InvCipher((state_t*)buf, ctx->RoundKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -490,40 +488,37 @@ void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
|
||||
|
||||
static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
|
||||
{
|
||||
buf[i] ^= Iv[i];
|
||||
}
|
||||
uint8_t i;
|
||||
for (i = 0; i < AES_BLOCKLEN; ++i) { // The block in AES is always 128bit no matter the key size
|
||||
buf[i] ^= Iv[i];
|
||||
}
|
||||
}
|
||||
|
||||
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t *Iv = ctx->Iv;
|
||||
for (i = 0; i < length; i += AES_BLOCKLEN)
|
||||
{
|
||||
XorWithIv(buf, Iv);
|
||||
Cipher((state_t*)buf, ctx->RoundKey);
|
||||
Iv = buf;
|
||||
buf += AES_BLOCKLEN;
|
||||
}
|
||||
/* store Iv in ctx for next call */
|
||||
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
|
||||
size_t i;
|
||||
uint8_t *Iv = ctx->Iv;
|
||||
for (i = 0; i < length; i += AES_BLOCKLEN) {
|
||||
XorWithIv(buf, Iv);
|
||||
Cipher((state_t*)buf, ctx->RoundKey);
|
||||
Iv = buf;
|
||||
buf += AES_BLOCKLEN;
|
||||
}
|
||||
/* store Iv in ctx for next call */
|
||||
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
|
||||
}
|
||||
|
||||
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t storeNextIv[AES_BLOCKLEN];
|
||||
for (i = 0; i < length; i += AES_BLOCKLEN)
|
||||
{
|
||||
memcpy(storeNextIv, buf, AES_BLOCKLEN);
|
||||
InvCipher((state_t*)buf, ctx->RoundKey);
|
||||
XorWithIv(buf, ctx->Iv);
|
||||
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
|
||||
buf += AES_BLOCKLEN;
|
||||
}
|
||||
size_t i;
|
||||
uint8_t storeNextIv[AES_BLOCKLEN];
|
||||
for (i = 0; i < length; i += AES_BLOCKLEN) {
|
||||
memcpy(storeNextIv, buf, AES_BLOCKLEN);
|
||||
InvCipher((state_t*)buf, ctx->RoundKey);
|
||||
XorWithIv(buf, ctx->Iv);
|
||||
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
|
||||
buf += AES_BLOCKLEN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -536,35 +531,31 @@ void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
|
||||
/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
|
||||
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
|
||||
{
|
||||
uint8_t buffer[AES_BLOCKLEN];
|
||||
|
||||
size_t i;
|
||||
int bi;
|
||||
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
|
||||
{
|
||||
if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
|
||||
{
|
||||
|
||||
memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
|
||||
Cipher((state_t*)buffer,ctx->RoundKey);
|
||||
uint8_t buffer[AES_BLOCKLEN];
|
||||
|
||||
/* Increment Iv and handle overflow */
|
||||
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
|
||||
{
|
||||
/* inc will overflow */
|
||||
if (ctx->Iv[bi] == 255)
|
||||
{
|
||||
ctx->Iv[bi] = 0;
|
||||
continue;
|
||||
}
|
||||
ctx->Iv[bi] += 1;
|
||||
break;
|
||||
}
|
||||
bi = 0;
|
||||
size_t i;
|
||||
int bi;
|
||||
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi) {
|
||||
if (bi == AES_BLOCKLEN) { /* we need to regen xor compliment in buffer */
|
||||
|
||||
memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
|
||||
Cipher((state_t*)buffer,ctx->RoundKey);
|
||||
|
||||
/* Increment Iv and handle overflow */
|
||||
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi) {
|
||||
/* inc will overflow */
|
||||
if (ctx->Iv[bi] == 255) {
|
||||
ctx->Iv[bi] = 0;
|
||||
continue;
|
||||
}
|
||||
ctx->Iv[bi] += 1;
|
||||
break;
|
||||
}
|
||||
bi = 0;
|
||||
}
|
||||
|
||||
buf[i] = (buf[i] ^ buffer[bi]);
|
||||
}
|
||||
|
||||
buf[i] = (buf[i] ^ buffer[bi]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if defined(CTR) && (CTR == 1)
|
||||
|
||||
35
common/aes.h
35
common/aes.h
@@ -12,15 +12,15 @@
|
||||
|
||||
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
|
||||
#ifndef CBC
|
||||
#define CBC 1
|
||||
#define CBC 1
|
||||
#endif
|
||||
|
||||
#ifndef ECB
|
||||
#define ECB 1
|
||||
#define ECB 1
|
||||
#endif
|
||||
|
||||
#ifndef CTR
|
||||
#define CTR 1
|
||||
#define CTR 1
|
||||
#endif
|
||||
|
||||
|
||||
@@ -31,21 +31,20 @@
|
||||
#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only
|
||||
|
||||
#if defined(AES256) && (AES256 == 1)
|
||||
#define AES_KEYLEN 32
|
||||
#define AES_keyExpSize 240
|
||||
#define AES_KEYLEN 32
|
||||
#define AES_keyExpSize 240
|
||||
#elif defined(AES192) && (AES192 == 1)
|
||||
#define AES_KEYLEN 24
|
||||
#define AES_keyExpSize 208
|
||||
#define AES_KEYLEN 24
|
||||
#define AES_keyExpSize 208
|
||||
#else
|
||||
#define AES_KEYLEN 16 // Key length in bytes
|
||||
#define AES_keyExpSize 176
|
||||
#define AES_KEYLEN 16 // Key length in bytes
|
||||
#define AES_keyExpSize 176
|
||||
#endif
|
||||
|
||||
struct AES_ctx
|
||||
{
|
||||
uint8_t RoundKey[AES_keyExpSize];
|
||||
struct AES_ctx {
|
||||
uint8_t RoundKey[AES_keyExpSize];
|
||||
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
|
||||
uint8_t Iv[AES_BLOCKLEN];
|
||||
uint8_t Iv[AES_BLOCKLEN];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -56,8 +55,8 @@ void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
|
||||
#endif
|
||||
|
||||
#if defined(ECB) && (ECB == 1)
|
||||
// buffer size is exactly AES_BLOCKLEN bytes;
|
||||
// you need only AES_init_ctx as IV is not used in ECB
|
||||
// buffer size is exactly AES_BLOCKLEN bytes;
|
||||
// you need only AES_init_ctx as IV is not used in ECB
|
||||
// NB: ECB is considered insecure for most uses
|
||||
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
|
||||
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
|
||||
@@ -69,7 +68,7 @@ void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
|
||||
// buffer size MUST be mutile of AES_BLOCKLEN;
|
||||
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
|
||||
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
|
||||
// no IV should ever be reused with the same key
|
||||
// no IV should ever be reused with the same key
|
||||
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
|
||||
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
|
||||
|
||||
@@ -78,11 +77,11 @@ void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
|
||||
|
||||
#if defined(CTR) && (CTR == 1)
|
||||
|
||||
// Same function for encrypting as for decrypting.
|
||||
// Same function for encrypting as for decrypting.
|
||||
// IV is incremented for every block, and used after encryption as XOR-compliment for output
|
||||
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
|
||||
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
|
||||
// no IV should ever be reused with the same key
|
||||
// no IV should ever be reused with the same key
|
||||
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
|
||||
|
||||
#endif // #if defined(CTR) && (CTR == 1)
|
||||
|
||||
1540
common/commands.h
1540
common/commands.h
File diff suppressed because it is too large
Load Diff
@@ -2,29 +2,34 @@
|
||||
#include <windows.h>
|
||||
|
||||
// A DLL runner.
|
||||
class DllRunner {
|
||||
class DllRunner
|
||||
{
|
||||
public:
|
||||
virtual ~DllRunner(){}
|
||||
virtual void* LoadLibraryA(const char* path, int size = 0) = 0;
|
||||
virtual FARPROC GetProcAddress(void* mod, const char* lpProcName) = 0;
|
||||
virtual BOOL FreeLibrary(void* mod) = 0;
|
||||
virtual ~DllRunner() {}
|
||||
virtual void* LoadLibraryA(const char* path, int size = 0) = 0;
|
||||
virtual FARPROC GetProcAddress(void* mod, const char* lpProcName) = 0;
|
||||
virtual BOOL FreeLibrary(void* mod) = 0;
|
||||
};
|
||||
|
||||
// Default DLL runner.
|
||||
class DefaultDllRunner : public DllRunner {
|
||||
class DefaultDllRunner : public DllRunner
|
||||
{
|
||||
private:
|
||||
std::string m_path;
|
||||
HMODULE m_mod;
|
||||
std::string m_path;
|
||||
HMODULE m_mod;
|
||||
public:
|
||||
DefaultDllRunner(const std::string &path="") :m_path(path), m_mod(nullptr) {}
|
||||
// Load DLL from the disk.
|
||||
virtual void* LoadLibraryA(const char* path, int size = 0) {
|
||||
return m_mod = ::LoadLibraryA(size ? m_path.c_str() : path);
|
||||
}
|
||||
virtual FARPROC GetProcAddress(void* mod, const char* lpProcName) {
|
||||
return ::GetProcAddress(m_mod, lpProcName);
|
||||
}
|
||||
virtual BOOL FreeLibrary(void* mod) {
|
||||
return ::FreeLibrary(m_mod);
|
||||
}
|
||||
DefaultDllRunner(const std::string &path="") :m_path(path), m_mod(nullptr) {}
|
||||
// Load DLL from the disk.
|
||||
virtual void* LoadLibraryA(const char* path, int size = 0)
|
||||
{
|
||||
return m_mod = ::LoadLibraryA(size ? m_path.c_str() : path);
|
||||
}
|
||||
virtual FARPROC GetProcAddress(void* mod, const char* lpProcName)
|
||||
{
|
||||
return ::GetProcAddress(m_mod, lpProcName);
|
||||
}
|
||||
virtual BOOL FreeLibrary(void* mod)
|
||||
{
|
||||
return ::FreeLibrary(m_mod);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,130 +2,134 @@
|
||||
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD>
|
||||
inline void encrypt_v1(unsigned char* data, size_t length, unsigned char key) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (i % 2 == 0) {
|
||||
data[i] = data[i] + key; // ż<><C5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> key
|
||||
}
|
||||
else {
|
||||
data[i] = data[i] - key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> key
|
||||
}
|
||||
}
|
||||
inline void encrypt_v1(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (i % 2 == 0) {
|
||||
data[i] = data[i] + key; // ż<><C5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> key
|
||||
} else {
|
||||
data[i] = data[i] - key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> key
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD>
|
||||
inline void decrypt_v1(unsigned char* data, size_t length, unsigned char key) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (i % 2 == 0) {
|
||||
data[i] = data[i] - key; // ż<><C5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> key <20><>ԭ
|
||||
}
|
||||
else {
|
||||
data[i] = data[i] + key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> key <20><>ԭ
|
||||
}
|
||||
}
|
||||
inline void decrypt_v1(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (i % 2 == 0) {
|
||||
data[i] = data[i] - key; // ż<><C5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> key <20><>ԭ
|
||||
} else {
|
||||
data[i] = data[i] + key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> key <20><>ԭ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD> - ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>ת
|
||||
inline void encrypt_v2(unsigned char* data, size_t length, unsigned char key) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
// ż<><C5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>key<65><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ1λ
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>key<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ1λ
|
||||
data[i] ^= key;
|
||||
if (i % 2 == 0) {
|
||||
data[i] = (data[i] << 1) | (data[i] >> 7); // <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ
|
||||
}
|
||||
else {
|
||||
data[i] = (data[i] >> 1) | (data[i] << 7); // <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ
|
||||
}
|
||||
}
|
||||
inline void encrypt_v2(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
// ż<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>key<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ1λ
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>key<65><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ1λ
|
||||
data[i] ^= key;
|
||||
if (i % 2 == 0) {
|
||||
data[i] = (data[i] << 1) | (data[i] >> 7); // <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ
|
||||
} else {
|
||||
data[i] = (data[i] >> 1) | (data[i] << 7); // <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD>
|
||||
inline void decrypt_v2(unsigned char* data, size_t length, unsigned char key) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
// <20><><EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (i % 2 == 0) {
|
||||
data[i] = (data[i] >> 1) | (data[i] << 7); // <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>ԭ
|
||||
}
|
||||
else {
|
||||
data[i] = (data[i] << 1) | (data[i] >> 7); // <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>ԭ
|
||||
}
|
||||
data[i] ^= key; // <20>ٴ<EFBFBD><D9B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ
|
||||
}
|
||||
inline void decrypt_v2(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
// <20><><EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (i % 2 == 0) {
|
||||
data[i] = (data[i] >> 1) | (data[i] << 7); // <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>ԭ
|
||||
} else {
|
||||
data[i] = (data[i] << 1) | (data[i] >> 7); // <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>ԭ
|
||||
}
|
||||
data[i] ^= key; // <20>ٴ<EFBFBD><D9B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD> V3 - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>key<65>Ķ<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD>
|
||||
inline void encrypt_v3(unsigned char* data, size_t length, unsigned char key) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
unsigned char dynamic_key = key + (i % 8); // <20><>̬<EFBFBD>仯<EFBFBD><E4BBAF>key<65><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (i % 3 == 0) {
|
||||
data[i] = (data[i] + dynamic_key) ^ dynamic_key; // <20>ӷ<EFBFBD> + <20><><EFBFBD><EFBFBD>
|
||||
}
|
||||
else if (i % 3 == 1) {
|
||||
data[i] = (data[i] ^ dynamic_key) - dynamic_key; // <20><><EFBFBD><EFBFBD> + <20><><EFBFBD><EFBFBD>
|
||||
}
|
||||
else {
|
||||
data[i] = ~(data[i] + dynamic_key); // ȡ<><C8A1> + <20>ӷ<EFBFBD>
|
||||
}
|
||||
}
|
||||
inline void encrypt_v3(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
unsigned char dynamic_key = key + (i % 8); // <20><>̬<EFBFBD>仯<EFBFBD><E4BBAF>key<65><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (i % 3 == 0) {
|
||||
data[i] = (data[i] + dynamic_key) ^ dynamic_key; // <20>ӷ<EFBFBD> + <20><><EFBFBD><EFBFBD>
|
||||
} else if (i % 3 == 1) {
|
||||
data[i] = (data[i] ^ dynamic_key) - dynamic_key; // <20><><EFBFBD><EFBFBD> + <20><><EFBFBD><EFBFBD>
|
||||
} else {
|
||||
data[i] = ~(data[i] + dynamic_key); // ȡ<><C8A1> + <20>ӷ<EFBFBD>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD> V3
|
||||
inline void decrypt_v3(unsigned char* data, size_t length, unsigned char key) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
unsigned char dynamic_key = key + (i % 8);
|
||||
if (i % 3 == 0) {
|
||||
data[i] = (data[i] ^ dynamic_key) - dynamic_key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ټ<EFBFBD>
|
||||
}
|
||||
else if (i % 3 == 1) {
|
||||
data[i] = (data[i] + dynamic_key) ^ dynamic_key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
else {
|
||||
data[i] = ~data[i] - dynamic_key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>ټ<EFBFBD>
|
||||
}
|
||||
}
|
||||
inline void decrypt_v3(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
unsigned char dynamic_key = key + (i % 8);
|
||||
if (i % 3 == 0) {
|
||||
data[i] = (data[i] ^ dynamic_key) - dynamic_key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ټ<EFBFBD>
|
||||
} else if (i % 3 == 1) {
|
||||
data[i] = (data[i] + dynamic_key) ^ dynamic_key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
} else {
|
||||
data[i] = ~data[i] - dynamic_key; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>ټ<EFBFBD>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD> V4 - <20><><EFBFBD><EFBFBD>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
inline void encrypt_v4(unsigned char* data, size_t length, unsigned char key) {
|
||||
unsigned char rand = key;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
rand = (rand * 13 + 17) % 256; // α<><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>LCG<43><47>
|
||||
data[i] ^= rand; // <EFBFBD><EFBFBD>α<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
inline void encrypt_v4(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
unsigned char rand = key;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
rand = (rand * 13 + 17) % 256; // α<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>LCG<EFBFBD><EFBFBD>
|
||||
data[i] ^= rand; // <20><>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD> V4<56><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><D4B7>ԣ<EFBFBD>
|
||||
inline void decrypt_v4(unsigned char* data, size_t length, unsigned char key) {
|
||||
encrypt_v4(data, length, key); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵĽ<DCB5><C4BD>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>һ<EFBFBD><D2BB>
|
||||
inline void decrypt_v4(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
encrypt_v4(data, length, key); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵĽ<DCB5><C4BD>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>һ<EFBFBD><D2BB>
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD> V5 - V5 <20>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD>̬<EFBFBD><CCAC>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD> + <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD>㣩
|
||||
inline void encrypt_v5(unsigned char* data, size_t length, unsigned char key) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
unsigned char dynamic_key = (key + i) ^ 0x55; // <20><>̬<EFBFBD><CCAC>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD>
|
||||
data[i] = ((data[i] + dynamic_key) ^ (dynamic_key << 3)) + (i % 7);
|
||||
}
|
||||
inline void encrypt_v5(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
unsigned char dynamic_key = (key + i) ^ 0x55; // <20><>̬<EFBFBD><CCAC>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD>
|
||||
data[i] = ((data[i] + dynamic_key) ^ (dynamic_key << 3)) + (i % 7);
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD> V5
|
||||
inline void decrypt_v5(unsigned char* data, size_t length, unsigned char key) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
unsigned char dynamic_key = (key + i) ^ 0x55;
|
||||
data[i] = (((data[i] - (i % 7)) ^ (dynamic_key << 3)) - dynamic_key);
|
||||
}
|
||||
inline void decrypt_v5(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
unsigned char dynamic_key = (key + i) ^ 0x55;
|
||||
data[i] = (((data[i] - (i % 7)) ^ (dynamic_key << 3)) - dynamic_key);
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD> V6<56><36><EFBFBD>Է<EFBFBD><D4B7>ԣ<EFBFBD> - V6 <20>汾<EFBFBD><E6B1BE>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + <20>Է<EFBFBD><D4B7>Խ<EFBFBD><D4BD>ܣ<EFBFBD>
|
||||
inline void encrypt_v6(unsigned char* data, size_t length, unsigned char key) {
|
||||
unsigned char rand = key;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
rand = (rand * 31 + 17) % 256; // <20><><EFBFBD><EFBFBD>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
data[i] ^= rand + i; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ̬
|
||||
}
|
||||
inline void encrypt_v6(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
unsigned char rand = key;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
rand = (rand * 31 + 17) % 256; // <20><><EFBFBD><EFBFBD>α<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
data[i] ^= rand + i; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ̬
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD> V6<56><36>ֱ<EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD> encrypt_v6 <20><><EFBFBD>ɣ<EFBFBD>
|
||||
inline void decrypt_v6(unsigned char* data, size_t length, unsigned char key) {
|
||||
encrypt_v6(data, length, key); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><D4B7><EFBFBD>
|
||||
inline void decrypt_v6(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
encrypt_v6(data, length, key); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><D4B7><EFBFBD>
|
||||
}
|
||||
|
||||
215
common/encrypt.h
215
common/encrypt.h
@@ -8,139 +8,156 @@ extern "C" {
|
||||
#define ALIGN16(n) ( (( (n) + 15) / 16) * 16 )
|
||||
|
||||
// Encoder interface. The default encoder will do nothing.
|
||||
class Encoder {
|
||||
class Encoder
|
||||
{
|
||||
public:
|
||||
virtual ~Encoder() {}
|
||||
// Encode data before compress.
|
||||
virtual void Encode(unsigned char* data, int len, unsigned char* param = 0) {}
|
||||
// Decode data after uncompress.
|
||||
virtual void Decode(unsigned char* data, int len, unsigned char* param = 0) {}
|
||||
virtual ~Encoder() {}
|
||||
// Encode data before compress.
|
||||
virtual void Encode(unsigned char* data, int len, unsigned char* param = 0) {}
|
||||
// Decode data after uncompress.
|
||||
virtual void Decode(unsigned char* data, int len, unsigned char* param = 0) {}
|
||||
};
|
||||
|
||||
// XOR Encoder implementation.
|
||||
class XOREncoder : public Encoder {
|
||||
class XOREncoder : public Encoder
|
||||
{
|
||||
private:
|
||||
std::vector<char> Keys;
|
||||
std::vector<char> Keys;
|
||||
|
||||
public:
|
||||
XOREncoder(const std::vector<char>& keys = { 0 }) : Keys(keys) {}
|
||||
XOREncoder(const std::vector<char>& keys = { 0 }) : Keys(keys) {}
|
||||
|
||||
virtual void Encode(unsigned char* data, int len, unsigned char* param = 0) {
|
||||
XOR(data, len, Keys);
|
||||
}
|
||||
virtual void Encode(unsigned char* data, int len, unsigned char* param = 0)
|
||||
{
|
||||
XOR(data, len, Keys);
|
||||
}
|
||||
|
||||
virtual void Decode(unsigned char* data, int len, unsigned char* param = 0) {
|
||||
static std::vector<char> reversed(Keys.rbegin(), Keys.rend());
|
||||
XOR(data, len, reversed);
|
||||
}
|
||||
virtual void Decode(unsigned char* data, int len, unsigned char* param = 0)
|
||||
{
|
||||
static std::vector<char> reversed(Keys.rbegin(), Keys.rend());
|
||||
XOR(data, len, reversed);
|
||||
}
|
||||
|
||||
protected:
|
||||
void XOR(unsigned char* data, int len, const std::vector<char>& keys) const {
|
||||
for (char key : keys) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
data[i] ^= key;
|
||||
}
|
||||
}
|
||||
}
|
||||
void XOR(unsigned char* data, int len, const std::vector<char>& keys) const
|
||||
{
|
||||
for (char key : keys) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
data[i] ^= key;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// XOREncoder16 A simple Encoder for the TCP body. It's using for `HELL` protocol.
|
||||
// This method is provided by ChatGPT. Encode data according to the 6th and 7th elem.
|
||||
class XOREncoder16 : public Encoder {
|
||||
class XOREncoder16 : public Encoder
|
||||
{
|
||||
private:
|
||||
static uint16_t pseudo_random(uint16_t seed, int index) {
|
||||
return ((seed ^ (index * 251 + 97)) * 733) ^ (seed >> 3);
|
||||
}
|
||||
static uint16_t pseudo_random(uint16_t seed, int index)
|
||||
{
|
||||
return ((seed ^ (index * 251 + 97)) * 733) ^ (seed >> 3);
|
||||
}
|
||||
|
||||
void encrypt_internal(unsigned char* data, int len, unsigned char k1, unsigned char k2) const {
|
||||
uint16_t key = ((k1 << 8) | k2);
|
||||
for (int i = 0; i < len; ++i) {
|
||||
data[i] ^= (k1 + i * 13) ^ (k2 ^ (i << 1));
|
||||
}
|
||||
void encrypt_internal(unsigned char* data, int len, unsigned char k1, unsigned char k2) const
|
||||
{
|
||||
uint16_t key = ((k1 << 8) | k2);
|
||||
for (int i = 0; i < len; ++i) {
|
||||
data[i] ^= (k1 + i * 13) ^ (k2 ^ (i << 1));
|
||||
}
|
||||
|
||||
// Two rounds of pseudo-random swaps
|
||||
for (int round = 0; round < 2; ++round) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
int j = pseudo_random(key, i + round * 100) % len;
|
||||
std::swap(data[i], data[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Two rounds of pseudo-random swaps
|
||||
for (int round = 0; round < 2; ++round) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
int j = pseudo_random(key, i + round * 100) % len;
|
||||
std::swap(data[i], data[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decrypt_internal(unsigned char* data, int len, unsigned char k1, unsigned char k2) const {
|
||||
uint16_t key = ((k1 << 8) | k2);
|
||||
for (int round = 1; round >= 0; --round) {
|
||||
for (int i = len - 1; i >= 0; --i) {
|
||||
int j = pseudo_random(key, i + round * 100) % len;
|
||||
std::swap(data[i], data[j]);
|
||||
}
|
||||
}
|
||||
void decrypt_internal(unsigned char* data, int len, unsigned char k1, unsigned char k2) const
|
||||
{
|
||||
uint16_t key = ((k1 << 8) | k2);
|
||||
for (int round = 1; round >= 0; --round) {
|
||||
for (int i = len - 1; i >= 0; --i) {
|
||||
int j = pseudo_random(key, i + round * 100) % len;
|
||||
std::swap(data[i], data[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; ++i) {
|
||||
data[i] ^= (k1 + i * 13) ^ (k2 ^ (i << 1));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < len; ++i) {
|
||||
data[i] ^= (k1 + i * 13) ^ (k2 ^ (i << 1));
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NO_AES
|
||||
void aes_encrypt(unsigned char* data, int len, const unsigned char* key, const unsigned char* iv) {
|
||||
if (!data || !key || !iv || len <= 0 || len % 16 != 0) {
|
||||
return; // AES CBC requires data length to be multiple of 16
|
||||
}
|
||||
void aes_encrypt(unsigned char* data, int len, const unsigned char* key, const unsigned char* iv)
|
||||
{
|
||||
if (!data || !key || !iv || len <= 0 || len % 16 != 0) {
|
||||
return; // AES CBC requires data length to be multiple of 16
|
||||
}
|
||||
|
||||
struct AES_ctx ctx;
|
||||
AES_init_ctx_iv(&ctx, key, iv);
|
||||
AES_CBC_encrypt_buffer(&ctx, data, len);
|
||||
}
|
||||
struct AES_ctx ctx;
|
||||
AES_init_ctx_iv(&ctx, key, iv);
|
||||
AES_CBC_encrypt_buffer(&ctx, data, len);
|
||||
}
|
||||
|
||||
void aes_decrypt(unsigned char* data, int len, const unsigned char* key, const unsigned char* iv) {
|
||||
if (!data || !key || !iv || len <= 0 || len % 16 != 0)
|
||||
return;
|
||||
void aes_decrypt(unsigned char* data, int len, const unsigned char* key, const unsigned char* iv)
|
||||
{
|
||||
if (!data || !key || !iv || len <= 0 || len % 16 != 0)
|
||||
return;
|
||||
|
||||
struct AES_ctx ctx;
|
||||
AES_init_ctx_iv(&ctx, key, iv);
|
||||
AES_CBC_decrypt_buffer(&ctx, data, len);
|
||||
}
|
||||
struct AES_ctx ctx;
|
||||
AES_init_ctx_iv(&ctx, key, iv);
|
||||
AES_CBC_decrypt_buffer(&ctx, data, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
XOREncoder16() {}
|
||||
XOREncoder16() {}
|
||||
|
||||
void Encode(unsigned char* data, int len, unsigned char* param) override {
|
||||
if (param[6] == 0 && param[7] == 0) return;
|
||||
if (param[7] == 1) {
|
||||
void Encode(unsigned char* data, int len, unsigned char* param) override
|
||||
{
|
||||
if (param[6] == 0 && param[7] == 0) return;
|
||||
if (param[7] == 1) {
|
||||
#ifndef NO_AES
|
||||
static const unsigned char aes_key[16] = {
|
||||
0x5A, 0xC3, 0x17, 0xF0, 0x89, 0xB6, 0x4E, 0x7D, 0x1A, 0x22, 0x9F, 0xC8, 0xD3, 0xE6, 0x73, 0xB1 };
|
||||
return aes_encrypt(data, len, aes_key, param + 8);
|
||||
static const unsigned char aes_key[16] = {
|
||||
0x5A, 0xC3, 0x17, 0xF0, 0x89, 0xB6, 0x4E, 0x7D, 0x1A, 0x22, 0x9F, 0xC8, 0xD3, 0xE6, 0x73, 0xB1
|
||||
};
|
||||
return aes_encrypt(data, len, aes_key, param + 8);
|
||||
#endif
|
||||
}
|
||||
encrypt_internal(data, len, param[6], param[7]);
|
||||
}
|
||||
}
|
||||
encrypt_internal(data, len, param[6], param[7]);
|
||||
}
|
||||
|
||||
void Decode(unsigned char* data, int len, unsigned char* param) override {
|
||||
if (param[6] == 0 && param[7] == 0) return;
|
||||
decrypt_internal(data, len, param[6], param[7]);
|
||||
}
|
||||
void Decode(unsigned char* data, int len, unsigned char* param) override
|
||||
{
|
||||
if (param[6] == 0 && param[7] == 0) return;
|
||||
decrypt_internal(data, len, param[6], param[7]);
|
||||
}
|
||||
};
|
||||
|
||||
class WinOsEncoder : public Encoder {
|
||||
class WinOsEncoder : public Encoder
|
||||
{
|
||||
public:
|
||||
virtual ~WinOsEncoder() {}
|
||||
// Encode data before compress.
|
||||
virtual void Encode(unsigned char* data, int len, unsigned char* param = 0) {
|
||||
return XOR(data, len, param);
|
||||
}
|
||||
// Decode data after uncompress.
|
||||
virtual void Decode(unsigned char* data, int len, unsigned char* param = 0) {
|
||||
return XOR(data, len, param);
|
||||
}
|
||||
virtual ~WinOsEncoder() {}
|
||||
// Encode data before compress.
|
||||
virtual void Encode(unsigned char* data, int len, unsigned char* param = 0)
|
||||
{
|
||||
return XOR(data, len, param);
|
||||
}
|
||||
// Decode data after uncompress.
|
||||
virtual void Decode(unsigned char* data, int len, unsigned char* param = 0)
|
||||
{
|
||||
return XOR(data, len, param);
|
||||
}
|
||||
private:
|
||||
void XOR(unsigned char* data, int len, unsigned char* password)
|
||||
{
|
||||
for (int i = 0, j = 0; i < len; i++) {
|
||||
((char*)data)[i] ^= (password[j++]) % 456 + 54;
|
||||
if (i % (10) == 0)
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
void XOR(unsigned char* data, int len, unsigned char* password)
|
||||
{
|
||||
for (int i = 0, j = 0; i < len; i++) {
|
||||
((char*)data)[i] ^= (password[j++]) % 456 + 54;
|
||||
if (i % (10) == 0)
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,26 +18,26 @@
|
||||
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Starting from this version, the main control program requires authorization and will automatically
|
||||
Starting from this version, the main control program requires authorization and will automatically
|
||||
connect to the authorization server. You may contact the author to request a license.
|
||||
If you have concerns about this mechanism, please use an earlier version (prior to v1.0.8).
|
||||
Alternatively, you may modify and compile the program yourself to bypass this requirement (see #91).
|
||||
|
||||
The author maintains and updates this software in their spare time. It is open-sourced solely for
|
||||
The author maintains and updates this software in their spare time. It is open-sourced solely for
|
||||
educational and non-commercial use; profit is not the primary goal.
|
||||
To use the official release version, a license must be obtained, which requires payment of a licensing fee.
|
||||
|
||||
You are free to modify the code and compile it for your own use (please refer to the note above: #91).
|
||||
You are free to modify the code and compile it for your own use (please refer to the note above: #91).
|
||||
No fees are charged in this case.
|
||||
Users are encouraged to first attempt self-compilation or test an earlier version to see if it meets their needs.
|
||||
Users are encouraged to first attempt self-compilation or test an earlier version to see if it meets their needs.
|
||||
If further functionality is required and budget is available, you may then consider obtaining a formal license.
|
||||
|
||||
If a license is obtained, future versions of the software can continue to be used under the same license,
|
||||
If a license is obtained, future versions of the software can continue to be used under the same license,
|
||||
and any remaining license time will be automatically carried over to the new version.
|
||||
|
||||
⚠️ This software is intended for lawful, legitimate, and compliant use only.
|
||||
Any use of this software for illegal, malicious, infringing, or unethical purposes is strictly prohibited.
|
||||
The author shall not be held liable for any legal issues, damages, or disputes resulting from misuse of
|
||||
The author shall not be held liable for any legal issues, damages, or disputes resulting from misuse of
|
||||
the software, and reserves the right to refuse or revoke authorization if improper use is discovered or suspected.
|
||||
*/
|
||||
|
||||
|
||||
265
common/header.h
265
common/header.h
@@ -7,16 +7,16 @@
|
||||
#define MSG_HEADER "HELL"
|
||||
|
||||
enum HeaderEncType {
|
||||
HeaderEncUnknown = -1,
|
||||
HeaderEncNone,
|
||||
HeaderEncV0,
|
||||
HeaderEncV1,
|
||||
HeaderEncV2,
|
||||
HeaderEncV3,
|
||||
HeaderEncV4,
|
||||
HeaderEncV5,
|
||||
HeaderEncV6,
|
||||
HeaderEncNum,
|
||||
HeaderEncUnknown = -1,
|
||||
HeaderEncNone,
|
||||
HeaderEncV0,
|
||||
HeaderEncV1,
|
||||
HeaderEncV2,
|
||||
HeaderEncV3,
|
||||
HeaderEncV4,
|
||||
HeaderEncV5,
|
||||
HeaderEncV6,
|
||||
HeaderEncNum,
|
||||
};
|
||||
|
||||
// <20><><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(4<>ֽ<EFBFBD>) + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(4<>ֽ<EFBFBD>)
|
||||
@@ -27,148 +27,157 @@ const int MIN_COMLEN = 12;
|
||||
|
||||
typedef void (*EncFun)(unsigned char* data, size_t length, unsigned char key);
|
||||
typedef void (*DecFun)(unsigned char* data, size_t length, unsigned char key);
|
||||
inline void default_encrypt(unsigned char* data, size_t length, unsigned char key) {
|
||||
data[FLAG_LENGTH - 2] = data[FLAG_LENGTH - 1] = 0;
|
||||
inline void default_encrypt(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
data[FLAG_LENGTH - 2] = data[FLAG_LENGTH - 1] = 0;
|
||||
}
|
||||
inline void default_decrypt(unsigned char* data, size_t length, unsigned char key) {
|
||||
inline void default_decrypt(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD>
|
||||
inline void encrypt(unsigned char* data, size_t length, unsigned char key) {
|
||||
if (key == 0) return;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
unsigned char k = static_cast<unsigned char>(key ^ (i * 31)); // <20><>̬<EFBFBD>Ŷ<EFBFBD> key
|
||||
int value = static_cast<int>(data[i]);
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
value += k;
|
||||
break;
|
||||
case 1:
|
||||
value = value ^ k;
|
||||
break;
|
||||
case 2:
|
||||
value -= k;
|
||||
break;
|
||||
case 3:
|
||||
value = ~(value ^ k); // <20>ಽ<EFBFBD>任<EFBFBD><E4BBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>
|
||||
break;
|
||||
}
|
||||
data[i] = static_cast<unsigned char>(value & 0xFF);
|
||||
}
|
||||
inline void encrypt(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
if (key == 0) return;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
unsigned char k = static_cast<unsigned char>(key ^ (i * 31)); // <20><>̬<EFBFBD>Ŷ<EFBFBD> key
|
||||
int value = static_cast<int>(data[i]);
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
value += k;
|
||||
break;
|
||||
case 1:
|
||||
value = value ^ k;
|
||||
break;
|
||||
case 2:
|
||||
value -= k;
|
||||
break;
|
||||
case 3:
|
||||
value = ~(value ^ k); // <20>ಽ<EFBFBD>任<EFBFBD><E4BBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>
|
||||
break;
|
||||
}
|
||||
data[i] = static_cast<unsigned char>(value & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD>
|
||||
inline void decrypt(unsigned char* data, size_t length, unsigned char key) {
|
||||
if (key == 0) return;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
unsigned char k = static_cast<unsigned char>(key ^ (i * 31));
|
||||
int value = static_cast<int>(data[i]);
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
value -= k;
|
||||
break;
|
||||
case 1:
|
||||
value = value ^ k;
|
||||
break;
|
||||
case 2:
|
||||
value += k;
|
||||
break;
|
||||
case 3:
|
||||
value = ~(value) ^ k; // <20><EFBFBD><E2BFAA><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
break;
|
||||
}
|
||||
data[i] = static_cast<unsigned char>(value & 0xFF);
|
||||
}
|
||||
inline void decrypt(unsigned char* data, size_t length, unsigned char key)
|
||||
{
|
||||
if (key == 0) return;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
unsigned char k = static_cast<unsigned char>(key ^ (i * 31));
|
||||
int value = static_cast<int>(data[i]);
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
value -= k;
|
||||
break;
|
||||
case 1:
|
||||
value = value ^ k;
|
||||
break;
|
||||
case 2:
|
||||
value += k;
|
||||
break;
|
||||
case 3:
|
||||
value = ~(value) ^ k; // <20><EFBFBD><E2BFAA><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
break;
|
||||
}
|
||||
data[i] = static_cast<unsigned char>(value & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
inline EncFun GetHeaderEncoder(HeaderEncType type) {
|
||||
static const DecFun methods[] = { default_encrypt, encrypt, encrypt_v1, encrypt_v2, encrypt_v3, encrypt_v4, encrypt_v5, encrypt_v6 };
|
||||
return methods[type];
|
||||
inline EncFun GetHeaderEncoder(HeaderEncType type)
|
||||
{
|
||||
static const DecFun methods[] = { default_encrypt, encrypt, encrypt_v1, encrypt_v2, encrypt_v3, encrypt_v4, encrypt_v5, encrypt_v6 };
|
||||
return methods[type];
|
||||
}
|
||||
|
||||
typedef struct HeaderFlag {
|
||||
char Data[FLAG_LENGTH + 1];
|
||||
HeaderFlag(const char header[FLAG_LENGTH + 1]) {
|
||||
memcpy(Data, header, sizeof(Data));
|
||||
}
|
||||
char& operator[](int i) {
|
||||
return Data[i];
|
||||
}
|
||||
const char operator[](int i) const {
|
||||
return Data[i];
|
||||
}
|
||||
const char* data() const {
|
||||
return Data;
|
||||
}
|
||||
}HeaderFlag;
|
||||
char Data[FLAG_LENGTH + 1];
|
||||
HeaderFlag(const char header[FLAG_LENGTH + 1])
|
||||
{
|
||||
memcpy(Data, header, sizeof(Data));
|
||||
}
|
||||
char& operator[](int i)
|
||||
{
|
||||
return Data[i];
|
||||
}
|
||||
const char operator[](int i) const
|
||||
{
|
||||
return Data[i];
|
||||
}
|
||||
const char* data() const
|
||||
{
|
||||
return Data;
|
||||
}
|
||||
} HeaderFlag;
|
||||
|
||||
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>ͷ
|
||||
inline HeaderFlag GetHead(EncFun enc) {
|
||||
char header[FLAG_LENGTH + 1] = { 'H','E','L','L', 0 };
|
||||
HeaderFlag H(header);
|
||||
unsigned char key = time(0) % 256;
|
||||
H[FLAG_LENGTH - 2] = key;
|
||||
H[FLAG_LENGTH - 1] = ~key;
|
||||
enc((unsigned char*)H.data(), FLAG_COMPLEN, H[FLAG_LENGTH - 2]);
|
||||
return H;
|
||||
inline HeaderFlag GetHead(EncFun enc)
|
||||
{
|
||||
char header[FLAG_LENGTH + 1] = { 'H','E','L','L', 0 };
|
||||
HeaderFlag H(header);
|
||||
unsigned char key = time(0) % 256;
|
||||
H[FLAG_LENGTH - 2] = key;
|
||||
H[FLAG_LENGTH - 1] = ~key;
|
||||
enc((unsigned char*)H.data(), FLAG_COMPLEN, H[FLAG_LENGTH - 2]);
|
||||
return H;
|
||||
}
|
||||
|
||||
enum FlagType {
|
||||
FLAG_WINOS = -1,
|
||||
FLAG_UNKNOWN = 0,
|
||||
FLAG_SHINE = 1,
|
||||
FLAG_FUCK = 2,
|
||||
FLAG_HELLO = 3,
|
||||
FLAG_HELL = 4,
|
||||
FLAG_WINOS = -1,
|
||||
FLAG_UNKNOWN = 0,
|
||||
FLAG_SHINE = 1,
|
||||
FLAG_FUCK = 2,
|
||||
FLAG_HELLO = 3,
|
||||
FLAG_HELL = 4,
|
||||
};
|
||||
|
||||
inline int compare(const char *flag, const char *magic, int len, DecFun dec, unsigned char key){
|
||||
unsigned char buf[32] = {};
|
||||
memcpy(buf, flag, MIN_COMLEN);
|
||||
dec(buf, len, key);
|
||||
if (memcmp(buf, magic, len) == 0) {
|
||||
memcpy((void*)flag, buf, MIN_COMLEN);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
inline int compare(const char *flag, const char *magic, int len, DecFun dec, unsigned char key)
|
||||
{
|
||||
unsigned char buf[32] = {};
|
||||
memcpy(buf, flag, MIN_COMLEN);
|
||||
dec(buf, len, key);
|
||||
if (memcmp(buf, magic, len) == 0) {
|
||||
memcpy((void*)flag, buf, MIN_COMLEN);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// <20>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD>ݰ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>Ľ<EFBFBD><C4BD>ܺ<EFBFBD><DCBA><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD>ݰ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD>н<EFBFBD><D0BD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>бȶ<D0B1>
|
||||
inline FlagType CheckHead(const char* flag, DecFun dec) {
|
||||
FlagType type = FLAG_UNKNOWN;
|
||||
if (compare(flag, skCrypt(MSG_HEADER), FLAG_COMPLEN, dec, flag[6]) == 0) {
|
||||
type = FLAG_HELL;
|
||||
}
|
||||
else if (compare(flag, skCrypt("Shine"), 5, dec, 0) == 0) {
|
||||
type = FLAG_SHINE;
|
||||
}
|
||||
else if (compare(flag, skCrypt("<<FUCK>>"), 8, dec, flag[9]) == 0) {
|
||||
type = FLAG_FUCK;
|
||||
}
|
||||
else if (compare(flag, skCrypt("Hello?"), 6, dec, flag[6]) == 0) {
|
||||
type = FLAG_HELLO;
|
||||
}
|
||||
else {
|
||||
type = FLAG_UNKNOWN;
|
||||
}
|
||||
return type;
|
||||
inline FlagType CheckHead(const char* flag, DecFun dec)
|
||||
{
|
||||
FlagType type = FLAG_UNKNOWN;
|
||||
if (compare(flag, skCrypt(MSG_HEADER), FLAG_COMPLEN, dec, flag[6]) == 0) {
|
||||
type = FLAG_HELL;
|
||||
} else if (compare(flag, skCrypt("Shine"), 5, dec, 0) == 0) {
|
||||
type = FLAG_SHINE;
|
||||
} else if (compare(flag, skCrypt("<<FUCK>>"), 8, dec, flag[9]) == 0) {
|
||||
type = FLAG_FUCK;
|
||||
} else if (compare(flag, skCrypt("Hello?"), 6, dec, flag[6]) == 0) {
|
||||
type = FLAG_HELLO;
|
||||
} else {
|
||||
type = FLAG_UNKNOWN;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Զ<EFBFBD><D4B6>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD><D4B1>ܼ<EFBFBD><DCBC><EFBFBD><EFBFBD>ϰ汾ͨѶЭ<D1B6><D0AD>
|
||||
inline FlagType CheckHead(char* flag, HeaderEncType& funcHit) {
|
||||
static const DecFun methods[] = { default_decrypt, decrypt, decrypt_v1, decrypt_v2, decrypt_v3, decrypt_v4, decrypt_v5, decrypt_v6 };
|
||||
static const int methodNum = sizeof(methods) / sizeof(DecFun);
|
||||
char buffer[MIN_COMLEN + 4] = {};
|
||||
for (int i = 0; i < methodNum; ++i) {
|
||||
memcpy(buffer, flag, MIN_COMLEN);
|
||||
FlagType type = CheckHead(buffer, methods[i]);
|
||||
if (type != FLAG_UNKNOWN) {
|
||||
memcpy(flag, buffer, MIN_COMLEN);
|
||||
funcHit = HeaderEncType(i);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
funcHit = HeaderEncUnknown;
|
||||
return FLAG_UNKNOWN;
|
||||
inline FlagType CheckHead(char* flag, HeaderEncType& funcHit)
|
||||
{
|
||||
static const DecFun methods[] = { default_decrypt, decrypt, decrypt_v1, decrypt_v2, decrypt_v3, decrypt_v4, decrypt_v5, decrypt_v6 };
|
||||
static const int methodNum = sizeof(methods) / sizeof(DecFun);
|
||||
char buffer[MIN_COMLEN + 4] = {};
|
||||
for (int i = 0; i < methodNum; ++i) {
|
||||
memcpy(buffer, flag, MIN_COMLEN);
|
||||
FlagType type = CheckHead(buffer, methods[i]);
|
||||
if (type != FLAG_UNKNOWN) {
|
||||
memcpy(flag, buffer, MIN_COMLEN);
|
||||
funcHit = HeaderEncType(i);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
funcHit = HeaderEncUnknown;
|
||||
return FLAG_UNKNOWN;
|
||||
}
|
||||
|
||||
1735
common/ikcp.c
1735
common/ikcp.c
File diff suppressed because it is too large
Load Diff
202
common/ikcp.h
202
common/ikcp.h
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// KCP - A Better ARQ Protocol Implementation
|
||||
// skywind3000 (at) gmail.com, 2010-2011
|
||||
//
|
||||
//
|
||||
// Features:
|
||||
// + Average RTT reduce 30% - 40% vs traditional ARQ like tcp.
|
||||
// + Maximum RTT reduce three times vs tcp.
|
||||
@@ -18,40 +18,40 @@
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// 32BIT INTEGER DEFINITION
|
||||
// 32BIT INTEGER DEFINITION
|
||||
//=====================================================================
|
||||
#ifndef __INTEGER_32_BITS__
|
||||
#define __INTEGER_32_BITS__
|
||||
#if defined(_WIN64) || defined(WIN64) || defined(__amd64__) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_IA64) || \
|
||||
defined(_M_AMD64)
|
||||
typedef unsigned int ISTDUINT32;
|
||||
typedef int ISTDINT32;
|
||||
typedef unsigned int ISTDUINT32;
|
||||
typedef int ISTDINT32;
|
||||
#elif defined(_WIN32) || defined(WIN32) || defined(__i386__) || \
|
||||
defined(__i386) || defined(_M_X86)
|
||||
typedef unsigned long ISTDUINT32;
|
||||
typedef long ISTDINT32;
|
||||
typedef unsigned long ISTDUINT32;
|
||||
typedef long ISTDINT32;
|
||||
#elif defined(__MACOS__)
|
||||
typedef UInt32 ISTDUINT32;
|
||||
typedef SInt32 ISTDINT32;
|
||||
typedef UInt32 ISTDUINT32;
|
||||
typedef SInt32 ISTDINT32;
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#include <sys/types.h>
|
||||
typedef u_int32_t ISTDUINT32;
|
||||
typedef int32_t ISTDINT32;
|
||||
#include <sys/types.h>
|
||||
typedef u_int32_t ISTDUINT32;
|
||||
typedef int32_t ISTDINT32;
|
||||
#elif defined(__BEOS__)
|
||||
#include <sys/inttypes.h>
|
||||
typedef u_int32_t ISTDUINT32;
|
||||
typedef int32_t ISTDINT32;
|
||||
#include <sys/inttypes.h>
|
||||
typedef u_int32_t ISTDUINT32;
|
||||
typedef int32_t ISTDINT32;
|
||||
#elif (defined(_MSC_VER) || defined(__BORLANDC__)) && (!defined(__MSDOS__))
|
||||
typedef unsigned __int32 ISTDUINT32;
|
||||
typedef __int32 ISTDINT32;
|
||||
typedef unsigned __int32 ISTDUINT32;
|
||||
typedef __int32 ISTDINT32;
|
||||
#elif defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
typedef uint32_t ISTDUINT32;
|
||||
typedef int32_t ISTDINT32;
|
||||
#else
|
||||
typedef unsigned long ISTDUINT32;
|
||||
typedef long ISTDINT32;
|
||||
#include <stdint.h>
|
||||
typedef uint32_t ISTDUINT32;
|
||||
typedef int32_t ISTDINT32;
|
||||
#else
|
||||
typedef unsigned long ISTDUINT32;
|
||||
typedef long ISTDINT32;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -119,7 +119,7 @@ typedef unsigned long long IUINT64;
|
||||
#elif (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__WATCOMC__))
|
||||
#define INLINE __inline
|
||||
#else
|
||||
#define INLINE
|
||||
#define INLINE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -129,20 +129,20 @@ typedef unsigned long long IUINT64;
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// QUEUE DEFINITION
|
||||
// QUEUE DEFINITION
|
||||
//=====================================================================
|
||||
#ifndef __IQUEUE_DEF__
|
||||
#define __IQUEUE_DEF__
|
||||
|
||||
struct IQUEUEHEAD {
|
||||
struct IQUEUEHEAD *next, *prev;
|
||||
struct IQUEUEHEAD *next, *prev;
|
||||
};
|
||||
|
||||
typedef struct IQUEUEHEAD iqueue_head;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// queue init
|
||||
// queue init
|
||||
//---------------------------------------------------------------------
|
||||
#define IQUEUE_HEAD_INIT(name) { &(name), &(name) }
|
||||
#define IQUEUE_HEAD(name) \
|
||||
@@ -160,7 +160,7 @@ typedef struct IQUEUEHEAD iqueue_head;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// queue operation
|
||||
// queue operation
|
||||
//---------------------------------------------------------------------
|
||||
#define IQUEUE_ADD(node, head) ( \
|
||||
(node)->prev = (head), (node)->next = (head)->next, \
|
||||
@@ -200,7 +200,7 @@ typedef struct IQUEUEHEAD iqueue_head;
|
||||
|
||||
#define iqueue_foreach_entry(pos, head) \
|
||||
for( (pos) = (head)->next; (pos) != (head) ; (pos) = (pos)->next )
|
||||
|
||||
|
||||
|
||||
#define __iqueue_splice(list, head) do { \
|
||||
iqueue_head *first = (list)->next, *last = (list)->prev; \
|
||||
@@ -228,92 +228,90 @@ typedef struct IQUEUEHEAD iqueue_head;
|
||||
// BYTE ORDER & ALIGNMENT
|
||||
//---------------------------------------------------------------------
|
||||
#ifndef IWORDS_BIG_ENDIAN
|
||||
#ifdef _BIG_ENDIAN_
|
||||
#if _BIG_ENDIAN_
|
||||
#define IWORDS_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#ifndef IWORDS_BIG_ENDIAN
|
||||
#if defined(__hppa__) || \
|
||||
#ifdef _BIG_ENDIAN_
|
||||
#if _BIG_ENDIAN_
|
||||
#define IWORDS_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#ifndef IWORDS_BIG_ENDIAN
|
||||
#if defined(__hppa__) || \
|
||||
defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
|
||||
(defined(__MIPS__) && defined(__MIPSEB__)) || \
|
||||
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
|
||||
defined(__sparc__) || defined(__powerpc__) || \
|
||||
defined(__mc68000__) || defined(__s390x__) || defined(__s390__)
|
||||
#define IWORDS_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#ifndef IWORDS_BIG_ENDIAN
|
||||
#define IWORDS_BIG_ENDIAN 0
|
||||
#endif
|
||||
#define IWORDS_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#ifndef IWORDS_BIG_ENDIAN
|
||||
#define IWORDS_BIG_ENDIAN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef IWORDS_MUST_ALIGN
|
||||
#if defined(__i386__) || defined(__i386) || defined(_i386_)
|
||||
#define IWORDS_MUST_ALIGN 0
|
||||
#elif defined(_M_IX86) || defined(_X86_) || defined(__x86_64__)
|
||||
#define IWORDS_MUST_ALIGN 0
|
||||
#elif defined(__amd64) || defined(__amd64__)
|
||||
#define IWORDS_MUST_ALIGN 0
|
||||
#else
|
||||
#define IWORDS_MUST_ALIGN 1
|
||||
#endif
|
||||
#if defined(__i386__) || defined(__i386) || defined(_i386_)
|
||||
#define IWORDS_MUST_ALIGN 0
|
||||
#elif defined(_M_IX86) || defined(_X86_) || defined(__x86_64__)
|
||||
#define IWORDS_MUST_ALIGN 0
|
||||
#elif defined(__amd64) || defined(__amd64__)
|
||||
#define IWORDS_MUST_ALIGN 0
|
||||
#else
|
||||
#define IWORDS_MUST_ALIGN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// SEGMENT
|
||||
//=====================================================================
|
||||
struct IKCPSEG
|
||||
{
|
||||
struct IQUEUEHEAD node;
|
||||
IUINT32 conv;
|
||||
IUINT32 cmd;
|
||||
IUINT32 frg;
|
||||
IUINT32 wnd;
|
||||
IUINT32 ts;
|
||||
IUINT32 sn;
|
||||
IUINT32 una;
|
||||
IUINT32 len;
|
||||
IUINT32 resendts;
|
||||
IUINT32 rto;
|
||||
IUINT32 fastack;
|
||||
IUINT32 xmit;
|
||||
char data[1];
|
||||
struct IKCPSEG {
|
||||
struct IQUEUEHEAD node;
|
||||
IUINT32 conv;
|
||||
IUINT32 cmd;
|
||||
IUINT32 frg;
|
||||
IUINT32 wnd;
|
||||
IUINT32 ts;
|
||||
IUINT32 sn;
|
||||
IUINT32 una;
|
||||
IUINT32 len;
|
||||
IUINT32 resendts;
|
||||
IUINT32 rto;
|
||||
IUINT32 fastack;
|
||||
IUINT32 xmit;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// IKCPCB
|
||||
//---------------------------------------------------------------------
|
||||
struct IKCPCB
|
||||
{
|
||||
IUINT32 conv, mtu, mss, state;
|
||||
IUINT32 snd_una, snd_nxt, rcv_nxt;
|
||||
IUINT32 ts_recent, ts_lastack, ssthresh;
|
||||
IINT32 rx_rttval, rx_srtt, rx_rto, rx_minrto;
|
||||
IUINT32 snd_wnd, rcv_wnd, rmt_wnd, cwnd, probe;
|
||||
IUINT32 current, interval, ts_flush, xmit;
|
||||
IUINT32 nrcv_buf, nsnd_buf;
|
||||
IUINT32 nrcv_que, nsnd_que;
|
||||
IUINT32 nodelay, updated;
|
||||
IUINT32 ts_probe, probe_wait;
|
||||
IUINT32 dead_link, incr;
|
||||
struct IQUEUEHEAD snd_queue;
|
||||
struct IQUEUEHEAD rcv_queue;
|
||||
struct IQUEUEHEAD snd_buf;
|
||||
struct IQUEUEHEAD rcv_buf;
|
||||
IUINT32 *acklist;
|
||||
IUINT32 ackcount;
|
||||
IUINT32 ackblock;
|
||||
void *user;
|
||||
char *buffer;
|
||||
int fastresend;
|
||||
int fastlimit;
|
||||
int nocwnd, stream;
|
||||
int logmask;
|
||||
int (*output)(const char *buf, int len, struct IKCPCB *kcp, void *user);
|
||||
void (*writelog)(const char *log, struct IKCPCB *kcp, void *user);
|
||||
struct IKCPCB {
|
||||
IUINT32 conv, mtu, mss, state;
|
||||
IUINT32 snd_una, snd_nxt, rcv_nxt;
|
||||
IUINT32 ts_recent, ts_lastack, ssthresh;
|
||||
IINT32 rx_rttval, rx_srtt, rx_rto, rx_minrto;
|
||||
IUINT32 snd_wnd, rcv_wnd, rmt_wnd, cwnd, probe;
|
||||
IUINT32 current, interval, ts_flush, xmit;
|
||||
IUINT32 nrcv_buf, nsnd_buf;
|
||||
IUINT32 nrcv_que, nsnd_que;
|
||||
IUINT32 nodelay, updated;
|
||||
IUINT32 ts_probe, probe_wait;
|
||||
IUINT32 dead_link, incr;
|
||||
struct IQUEUEHEAD snd_queue;
|
||||
struct IQUEUEHEAD rcv_queue;
|
||||
struct IQUEUEHEAD snd_buf;
|
||||
struct IQUEUEHEAD rcv_buf;
|
||||
IUINT32 *acklist;
|
||||
IUINT32 ackcount;
|
||||
IUINT32 ackblock;
|
||||
void *user;
|
||||
char *buffer;
|
||||
int fastresend;
|
||||
int fastlimit;
|
||||
int nocwnd, stream;
|
||||
int logmask;
|
||||
int (*output)(const char *buf, int len, struct IKCPCB *kcp, void *user);
|
||||
void (*writelog)(const char *log, struct IKCPCB *kcp, void *user);
|
||||
};
|
||||
|
||||
|
||||
@@ -349,8 +347,8 @@ ikcpcb* ikcp_create(IUINT32 conv, void *user);
|
||||
void ikcp_release(ikcpcb *kcp);
|
||||
|
||||
// set output callback, which will be invoked by kcp
|
||||
void ikcp_setoutput(ikcpcb *kcp, int (*output)(const char *buf, int len,
|
||||
ikcpcb *kcp, void *user));
|
||||
void ikcp_setoutput(ikcpcb *kcp, int (*output)(const char *buf, int len,
|
||||
ikcpcb *kcp, void *user));
|
||||
|
||||
// user/upper level recv: returns size, returns below zero for EAGAIN
|
||||
int ikcp_recv(ikcpcb *kcp, char *buffer, int len);
|
||||
@@ -358,17 +356,17 @@ int ikcp_recv(ikcpcb *kcp, char *buffer, int len);
|
||||
// user/upper level send, returns below zero for error
|
||||
int ikcp_send(ikcpcb *kcp, const char *buffer, int len);
|
||||
|
||||
// update state (call it repeatedly, every 10ms-100ms), or you can ask
|
||||
// update state (call it repeatedly, every 10ms-100ms), or you can ask
|
||||
// ikcp_check when to call it again (without ikcp_input/_send calling).
|
||||
// 'current' - current timestamp in millisec.
|
||||
// 'current' - current timestamp in millisec.
|
||||
void ikcp_update(ikcpcb *kcp, IUINT32 current);
|
||||
|
||||
// Determine when should you invoke ikcp_update:
|
||||
// returns when you should invoke ikcp_update in millisec, if there
|
||||
// returns when you should invoke ikcp_update in millisec, if there
|
||||
// is no ikcp_input/_send calling. you can call ikcp_update in that
|
||||
// time, instead of call update repeatly.
|
||||
// Important to reduce unnacessary ikcp_update invoking. use it to
|
||||
// schedule ikcp_update (eg. implementing an epoll-like mechanism,
|
||||
// Important to reduce unnacessary ikcp_update invoking. use it to
|
||||
// schedule ikcp_update (eg. implementing an epoll-like mechanism,
|
||||
// or optimize ikcp_update when handling massive kcp connections)
|
||||
IUINT32 ikcp_check(const ikcpcb *kcp, IUINT32 current);
|
||||
|
||||
@@ -392,7 +390,7 @@ int ikcp_waitsnd(const ikcpcb *kcp);
|
||||
|
||||
// fastest: ikcp_nodelay(kcp, 1, 20, 2, 1)
|
||||
// nodelay: 0:disable(default), 1:enable
|
||||
// interval: internal update timer interval in millisec, default is 100ms
|
||||
// interval: internal update timer interval in millisec, default is 100ms
|
||||
// resend: 0:disable fast resend(default), 1:enable fast resend
|
||||
// nc: 0:normal congestion control(default), 1:disable congestion control
|
||||
int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc);
|
||||
|
||||
316
common/iniFile.h
316
common/iniFile.h
@@ -9,208 +9,204 @@
|
||||
class config
|
||||
{
|
||||
private:
|
||||
char m_IniFilePath[_MAX_PATH] = { 0 };
|
||||
char m_IniFilePath[_MAX_PATH] = { 0 };
|
||||
|
||||
public:
|
||||
virtual ~config() {}
|
||||
virtual ~config() {}
|
||||
|
||||
config(const std::string& path="")
|
||||
{
|
||||
if (path.length() == 0) {
|
||||
::GetModuleFileNameA(NULL, m_IniFilePath, sizeof(m_IniFilePath));
|
||||
GET_FILEPATH(m_IniFilePath, "settings.ini");
|
||||
} else {
|
||||
memcpy(m_IniFilePath, path.c_str(), path.length());
|
||||
}
|
||||
}
|
||||
config(const std::string& path="")
|
||||
{
|
||||
if (path.length() == 0) {
|
||||
::GetModuleFileNameA(NULL, m_IniFilePath, sizeof(m_IniFilePath));
|
||||
GET_FILEPATH(m_IniFilePath, "settings.ini");
|
||||
} else {
|
||||
memcpy(m_IniFilePath, path.c_str(), path.length());
|
||||
}
|
||||
}
|
||||
|
||||
virtual int GetInt(const std::string& MainKey, const std::string& SubKey, int nDef=0)
|
||||
{
|
||||
return ::GetPrivateProfileIntA(MainKey.c_str(), SubKey.c_str(), nDef, m_IniFilePath);
|
||||
}
|
||||
virtual int GetInt(const std::string& MainKey, const std::string& SubKey, int nDef=0)
|
||||
{
|
||||
return ::GetPrivateProfileIntA(MainKey.c_str(), SubKey.c_str(), nDef, m_IniFilePath);
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еĵ<D0B5>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
virtual int Get1Int(const std::string& MainKey, const std::string& SubKey, char ch=';', int nDef=0)
|
||||
{
|
||||
std::string s = GetStr(MainKey, SubKey, "");
|
||||
s = StringToVector(s, ch)[0];
|
||||
return s.empty() ? nDef : atoi(s.c_str());
|
||||
}
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еĵ<D0B5>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
virtual int Get1Int(const std::string& MainKey, const std::string& SubKey, char ch=';', int nDef=0)
|
||||
{
|
||||
std::string s = GetStr(MainKey, SubKey, "");
|
||||
s = StringToVector(s, ch)[0];
|
||||
return s.empty() ? nDef : atoi(s.c_str());
|
||||
}
|
||||
|
||||
virtual bool SetInt(const std::string& MainKey, const std::string& SubKey, int Data)
|
||||
{
|
||||
std::string strData = std::to_string(Data);
|
||||
return ::WritePrivateProfileStringA(MainKey.c_str(), SubKey.c_str(), strData.c_str(), m_IniFilePath);
|
||||
}
|
||||
virtual bool SetInt(const std::string& MainKey, const std::string& SubKey, int Data)
|
||||
{
|
||||
std::string strData = std::to_string(Data);
|
||||
return ::WritePrivateProfileStringA(MainKey.c_str(), SubKey.c_str(), strData.c_str(), m_IniFilePath);
|
||||
}
|
||||
|
||||
virtual std::string GetStr(const std::string& MainKey, const std::string& SubKey, const std::string& def = "")
|
||||
{
|
||||
char buf[_MAX_PATH] = { 0 };
|
||||
::GetPrivateProfileStringA(MainKey.c_str(), SubKey.c_str(), def.c_str(), buf, sizeof(buf), m_IniFilePath);
|
||||
return std::string(buf);
|
||||
}
|
||||
virtual std::string GetStr(const std::string& MainKey, const std::string& SubKey, const std::string& def = "")
|
||||
{
|
||||
char buf[_MAX_PATH] = { 0 };
|
||||
::GetPrivateProfileStringA(MainKey.c_str(), SubKey.c_str(), def.c_str(), buf, sizeof(buf), m_IniFilePath);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
virtual bool SetStr(const std::string& MainKey, const std::string& SubKey, const std::string& Data)
|
||||
{
|
||||
return ::WritePrivateProfileStringA(MainKey.c_str(), SubKey.c_str(), Data.c_str(), m_IniFilePath);
|
||||
}
|
||||
virtual bool SetStr(const std::string& MainKey, const std::string& SubKey, const std::string& Data)
|
||||
{
|
||||
return ::WritePrivateProfileStringA(MainKey.c_str(), SubKey.c_str(), Data.c_str(), m_IniFilePath);
|
||||
}
|
||||
};
|
||||
|
||||
// <20><><EFBFBD>ö<EFBFBD>ȡ<EFBFBD><C8A1>: ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
class iniFile : public config
|
||||
{
|
||||
private:
|
||||
HKEY m_hRootKey;
|
||||
std::string m_SubKeyPath;
|
||||
HKEY m_hRootKey;
|
||||
std::string m_SubKeyPath;
|
||||
|
||||
public:
|
||||
~iniFile() {}
|
||||
~iniFile() {}
|
||||
|
||||
iniFile(const std::string& path = YAMA_PATH)
|
||||
{
|
||||
m_hRootKey = HKEY_CURRENT_USER;
|
||||
m_SubKeyPath = path;
|
||||
}
|
||||
iniFile(const std::string& path = YAMA_PATH)
|
||||
{
|
||||
m_hRootKey = HKEY_CURRENT_USER;
|
||||
m_SubKeyPath = path;
|
||||
}
|
||||
|
||||
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>дΪ<D0B4>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
bool SetInt(const std::string& MainKey, const std::string& SubKey, int Data) override
|
||||
{
|
||||
return SetStr(MainKey, SubKey, std::to_string(Data));
|
||||
}
|
||||
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>дΪ<D0B4>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
bool SetInt(const std::string& MainKey, const std::string& SubKey, int Data) override
|
||||
{
|
||||
return SetStr(MainKey, SubKey, std::to_string(Data));
|
||||
}
|
||||
|
||||
// д<><D0B4><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
bool SetStr(const std::string& MainKey, const std::string& SubKey, const std::string& Data) override
|
||||
{
|
||||
std::string fullPath = m_SubKeyPath + "\\" + MainKey;
|
||||
HKEY hKey;
|
||||
if (RegCreateKeyExA(m_hRootKey, fullPath.c_str(), 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
|
||||
return false;
|
||||
// д<><D0B4><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
bool SetStr(const std::string& MainKey, const std::string& SubKey, const std::string& Data) override
|
||||
{
|
||||
std::string fullPath = m_SubKeyPath + "\\" + MainKey;
|
||||
HKEY hKey;
|
||||
if (RegCreateKeyExA(m_hRootKey, fullPath.c_str(), 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
|
||||
return false;
|
||||
|
||||
bool bRet = (RegSetValueExA(hKey, SubKey.c_str(), 0, REG_SZ,
|
||||
reinterpret_cast<const BYTE*>(Data.c_str()),
|
||||
static_cast<DWORD>(Data.size() + 1)) == ERROR_SUCCESS);
|
||||
RegCloseKey(hKey);
|
||||
return bRet;
|
||||
}
|
||||
bool bRet = (RegSetValueExA(hKey, SubKey.c_str(), 0, REG_SZ,
|
||||
reinterpret_cast<const BYTE*>(Data.c_str()),
|
||||
static_cast<DWORD>(Data.size() + 1)) == ERROR_SUCCESS);
|
||||
RegCloseKey(hKey);
|
||||
return bRet;
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
std::string GetStr(const std::string& MainKey, const std::string& SubKey, const std::string& def = "") override
|
||||
{
|
||||
std::string fullPath = m_SubKeyPath + "\\" + MainKey;
|
||||
HKEY hKey;
|
||||
char buffer[512] = { 0 };
|
||||
DWORD dwSize = sizeof(buffer);
|
||||
std::string result = def;
|
||||
// <20><>ȡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
std::string GetStr(const std::string& MainKey, const std::string& SubKey, const std::string& def = "") override
|
||||
{
|
||||
std::string fullPath = m_SubKeyPath + "\\" + MainKey;
|
||||
HKEY hKey;
|
||||
char buffer[512] = { 0 };
|
||||
DWORD dwSize = sizeof(buffer);
|
||||
std::string result = def;
|
||||
|
||||
if (RegOpenKeyExA(m_hRootKey, fullPath.c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD dwType = REG_SZ;
|
||||
if (RegQueryValueExA(hKey, SubKey.c_str(), NULL, &dwType, reinterpret_cast<LPBYTE>(buffer), &dwSize) == ERROR_SUCCESS &&
|
||||
dwType == REG_SZ)
|
||||
{
|
||||
result = buffer;
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (RegOpenKeyExA(m_hRootKey, fullPath.c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
||||
DWORD dwType = REG_SZ;
|
||||
if (RegQueryValueExA(hKey, SubKey.c_str(), NULL, &dwType, reinterpret_cast<LPBYTE>(buffer), &dwSize) == ERROR_SUCCESS &&
|
||||
dwType == REG_SZ) {
|
||||
result = buffer;
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
|
||||
int GetInt(const std::string& MainKey, const std::string& SubKey, int defVal = 0) override
|
||||
{
|
||||
std::string val = GetStr(MainKey, SubKey);
|
||||
if (val.empty())
|
||||
return defVal;
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
|
||||
int GetInt(const std::string& MainKey, const std::string& SubKey, int defVal = 0) override
|
||||
{
|
||||
std::string val = GetStr(MainKey, SubKey);
|
||||
if (val.empty())
|
||||
return defVal;
|
||||
|
||||
try {
|
||||
return std::stoi(val);
|
||||
}
|
||||
catch (...) {
|
||||
return defVal;
|
||||
}
|
||||
}
|
||||
try {
|
||||
return std::stoi(val);
|
||||
} catch (...) {
|
||||
return defVal;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class binFile : public config
|
||||
{
|
||||
private:
|
||||
HKEY m_hRootKey;
|
||||
std::string m_SubKeyPath;
|
||||
HKEY m_hRootKey;
|
||||
std::string m_SubKeyPath;
|
||||
|
||||
public:
|
||||
~binFile() {}
|
||||
~binFile() {}
|
||||
|
||||
binFile(const std::string& path = CLIENT_PATH)
|
||||
{
|
||||
m_hRootKey = HKEY_CURRENT_USER;
|
||||
m_SubKeyPath = path;
|
||||
}
|
||||
binFile(const std::string& path = CLIENT_PATH)
|
||||
{
|
||||
m_hRootKey = HKEY_CURRENT_USER;
|
||||
m_SubKeyPath = path;
|
||||
}
|
||||
|
||||
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>дΪ<D0B4><CEAA><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>
|
||||
bool SetInt(const std::string& MainKey, const std::string& SubKey, int Data) override
|
||||
{
|
||||
return SetBinary(MainKey, SubKey, reinterpret_cast<const BYTE*>(&Data), sizeof(int));
|
||||
}
|
||||
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>дΪ<D0B4><CEAA><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>
|
||||
bool SetInt(const std::string& MainKey, const std::string& SubKey, int Data) override
|
||||
{
|
||||
return SetBinary(MainKey, SubKey, reinterpret_cast<const BYTE*>(&Data), sizeof(int));
|
||||
}
|
||||
|
||||
// д<><D0B4><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>Ʒ<EFBFBD>ʽ<EFBFBD><CABD>
|
||||
bool SetStr(const std::string& MainKey, const std::string& SubKey, const std::string& Data) override
|
||||
{
|
||||
return SetBinary(MainKey, SubKey, reinterpret_cast<const BYTE*>(Data.data()), static_cast<DWORD>(Data.size()));
|
||||
}
|
||||
// д<><D0B4><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>Ʒ<EFBFBD>ʽ<EFBFBD><CABD>
|
||||
bool SetStr(const std::string& MainKey, const std::string& SubKey, const std::string& Data) override
|
||||
{
|
||||
return SetBinary(MainKey, SubKey, reinterpret_cast<const BYTE*>(Data.data()), static_cast<DWORD>(Data.size()));
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
|
||||
std::string GetStr(const std::string& MainKey, const std::string& SubKey, const std::string& def = "") override
|
||||
{
|
||||
std::vector<BYTE> buffer;
|
||||
if (!GetBinary(MainKey, SubKey, buffer))
|
||||
return def;
|
||||
// <20><>ȡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
|
||||
std::string GetStr(const std::string& MainKey, const std::string& SubKey, const std::string& def = "") override
|
||||
{
|
||||
std::vector<BYTE> buffer;
|
||||
if (!GetBinary(MainKey, SubKey, buffer))
|
||||
return def;
|
||||
|
||||
return std::string(buffer.begin(), buffer.end());
|
||||
}
|
||||
return std::string(buffer.begin(), buffer.end());
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int GetInt(const std::string& MainKey, const std::string& SubKey, int defVal = 0) override
|
||||
{
|
||||
std::vector<BYTE> buffer;
|
||||
if (!GetBinary(MainKey, SubKey, buffer) || buffer.size() < sizeof(int))
|
||||
return defVal;
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int GetInt(const std::string& MainKey, const std::string& SubKey, int defVal = 0) override
|
||||
{
|
||||
std::vector<BYTE> buffer;
|
||||
if (!GetBinary(MainKey, SubKey, buffer) || buffer.size() < sizeof(int))
|
||||
return defVal;
|
||||
|
||||
int value = 0;
|
||||
memcpy(&value, buffer.data(), sizeof(int));
|
||||
return value;
|
||||
}
|
||||
int value = 0;
|
||||
memcpy(&value, buffer.data(), sizeof(int));
|
||||
return value;
|
||||
}
|
||||
|
||||
private:
|
||||
bool SetBinary(const std::string& MainKey, const std::string& SubKey, const BYTE* data, DWORD size)
|
||||
{
|
||||
std::string fullPath = m_SubKeyPath + "\\" + MainKey;
|
||||
HKEY hKey;
|
||||
if (RegCreateKeyExA(m_hRootKey, fullPath.c_str(), 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
|
||||
return false;
|
||||
bool SetBinary(const std::string& MainKey, const std::string& SubKey, const BYTE* data, DWORD size)
|
||||
{
|
||||
std::string fullPath = m_SubKeyPath + "\\" + MainKey;
|
||||
HKEY hKey;
|
||||
if (RegCreateKeyExA(m_hRootKey, fullPath.c_str(), 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
|
||||
return false;
|
||||
|
||||
bool bRet = (RegSetValueExA(hKey, SubKey.c_str(), 0, REG_BINARY, data, size) == ERROR_SUCCESS);
|
||||
RegCloseKey(hKey);
|
||||
return bRet;
|
||||
}
|
||||
bool bRet = (RegSetValueExA(hKey, SubKey.c_str(), 0, REG_BINARY, data, size) == ERROR_SUCCESS);
|
||||
RegCloseKey(hKey);
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool GetBinary(const std::string& MainKey, const std::string& SubKey, std::vector<BYTE>& outData)
|
||||
{
|
||||
std::string fullPath = m_SubKeyPath + "\\" + MainKey;
|
||||
HKEY hKey;
|
||||
if (RegOpenKeyExA(m_hRootKey, fullPath.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
||||
return false;
|
||||
bool GetBinary(const std::string& MainKey, const std::string& SubKey, std::vector<BYTE>& outData)
|
||||
{
|
||||
std::string fullPath = m_SubKeyPath + "\\" + MainKey;
|
||||
HKEY hKey;
|
||||
if (RegOpenKeyExA(m_hRootKey, fullPath.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
||||
return false;
|
||||
|
||||
DWORD dwType = 0;
|
||||
DWORD dwSize = 0;
|
||||
if (RegQueryValueExA(hKey, SubKey.c_str(), NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS || dwType != REG_BINARY)
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
return false;
|
||||
}
|
||||
DWORD dwType = 0;
|
||||
DWORD dwSize = 0;
|
||||
if (RegQueryValueExA(hKey, SubKey.c_str(), NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS || dwType != REG_BINARY) {
|
||||
RegCloseKey(hKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
outData.resize(dwSize);
|
||||
bool bRet = (RegQueryValueExA(hKey, SubKey.c_str(), NULL, NULL, outData.data(), &dwSize) == ERROR_SUCCESS);
|
||||
RegCloseKey(hKey);
|
||||
return bRet;
|
||||
}
|
||||
outData.resize(dwSize);
|
||||
bool bRet = (RegQueryValueExA(hKey, SubKey.c_str(), NULL, NULL, outData.data(), &dwSize) == ERROR_SUCCESS);
|
||||
RegCloseKey(hKey);
|
||||
return bRet;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,50 +6,55 @@
|
||||
|
||||
// Encode for IP and Port.
|
||||
// provided by ChatGPT.
|
||||
class StreamCipher {
|
||||
class StreamCipher
|
||||
{
|
||||
private:
|
||||
uint32_t state;
|
||||
uint32_t state;
|
||||
|
||||
// <20><EFBFBD><F2B5A5B7><EFBFBD><EFBFBD><EFBFBD>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint8_t prngNext() {
|
||||
// <20><><EFBFBD>ӣ<EFBFBD>xorshift32<33><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
state ^= (state << 13);
|
||||
state ^= (state >> 17);
|
||||
state ^= (state << 5);
|
||||
// <20>ٻ<EFBFBD><D9BB><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ķ<F2B5A5B5><C4B7><EFBFBD><EFBFBD>Ա任
|
||||
uint8_t out = (state & 0xFF) ^ ((state >> 8) & 0xFF);
|
||||
return out;
|
||||
}
|
||||
// <20><EFBFBD><F2B5A5B7><EFBFBD><EFBFBD><EFBFBD>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint8_t prngNext()
|
||||
{
|
||||
// <20><><EFBFBD>ӣ<EFBFBD>xorshift32<33><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
state ^= (state << 13);
|
||||
state ^= (state >> 17);
|
||||
state ^= (state << 5);
|
||||
// <20>ٻ<EFBFBD><D9BB><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ķ<F2B5A5B5><C4B7><EFBFBD><EFBFBD>Ա任
|
||||
uint8_t out = (state & 0xFF) ^ ((state >> 8) & 0xFF);
|
||||
return out;
|
||||
}
|
||||
|
||||
public:
|
||||
StreamCipher(uint32_t key) : state(key) {}
|
||||
StreamCipher(uint32_t key) : state(key) {}
|
||||
|
||||
// <20><><EFBFBD>ܽ<EFBFBD><DCBD>ܣ<EFBFBD><DCA3>Գƣ<D4B3><C6A3><EFBFBD><EFBFBD>Ȳ<EFBFBD><C8B2>䣩
|
||||
void process(uint8_t* data, size_t len) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
data[i] ^= prngNext();
|
||||
}
|
||||
}
|
||||
// <20><><EFBFBD>ܽ<EFBFBD><DCBD>ܣ<EFBFBD><DCA3>Գƣ<D4B3><C6A3><EFBFBD><EFBFBD>Ȳ<EFBFBD><C8B2>䣩
|
||||
void process(uint8_t* data, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
data[i] ^= prngNext();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class PrintableXORCipher {
|
||||
class PrintableXORCipher
|
||||
{
|
||||
public:
|
||||
// <20>ԳƼӽ<C6BC><D3BD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ɴ<EFBFBD>ӡ<EFBFBD>ַ<EFBFBD>
|
||||
// ǰ<><EFBFBD><E1A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>32~126<32><36>Χ<EFBFBD><CEA7><EFBFBD>ַ<EFBFBD>
|
||||
void process(char* data, size_t len) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
char c = data[i];
|
||||
// <20><>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ǿɴ<C7BF>ӡ<EFBFBD><D3A1>Χ
|
||||
if (c < 32 || c > 126) {
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD>ӡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
continue;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD>0x55<35><35>'U'<27><><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>32~126֮<36><D6AE>
|
||||
char encrypted = c ^ 0x55;
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD>Χ<EFBFBD>ڣ<EFBFBD><DAA3>Ӽ<F2B5A5BC>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>
|
||||
if (encrypted < 32) encrypted += 95;
|
||||
if (encrypted > 126) encrypted -= 95;
|
||||
data[i] = encrypted;
|
||||
}
|
||||
}
|
||||
// <20>ԳƼӽ<C6BC><D3BD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ɴ<EFBFBD>ӡ<EFBFBD>ַ<EFBFBD>
|
||||
// ǰ<><EFBFBD><E1A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>32~126<32><36>Χ<EFBFBD><CEA7><EFBFBD>ַ<EFBFBD>
|
||||
void process(char* data, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
char c = data[i];
|
||||
// <20><>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ǿɴ<C7BF>ӡ<EFBFBD><D3A1>Χ
|
||||
if (c < 32 || c > 126) {
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD>ӡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
continue;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD>0x55<35><35>'U'<27><><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>32~126֮<36><D6AE>
|
||||
char encrypted = c ^ 0x55;
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD>Χ<EFBFBD>ڣ<EFBFBD><DAA3>Ӽ<F2B5A5BC>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>
|
||||
if (encrypted < 32) encrypted += 95;
|
||||
if (encrypted > 126) encrypted -= 95;
|
||||
data[i] = encrypted;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -24,16 +24,16 @@
|
||||
#pragma comment(lib, "wininet.lib")
|
||||
#pragma comment(lib, "Iphlpapi.lib")
|
||||
|
||||
inline void splitIpPort(const std::string& input, std::string& ip, std::string& port) {
|
||||
size_t pos = input.find(':');
|
||||
if (pos != std::string::npos) {
|
||||
ip = input.substr(0, pos);
|
||||
port = input.substr(pos + 1);
|
||||
}
|
||||
else {
|
||||
ip = input;
|
||||
port = "";
|
||||
}
|
||||
inline void splitIpPort(const std::string& input, std::string& ip, std::string& port)
|
||||
{
|
||||
size_t pos = input.find(':');
|
||||
if (pos != std::string::npos) {
|
||||
ip = input.substr(0, pos);
|
||||
port = input.substr(pos + 1);
|
||||
} else {
|
||||
ip = input;
|
||||
port = "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,205 +43,210 @@ inline void splitIpPort(const std::string& input, std::string& ip, std::string&
|
||||
class IPConverter
|
||||
{
|
||||
public:
|
||||
std::string IPtoAddress(const std::string& ip) { return "implement me"; }
|
||||
std::string IPtoAddress(const std::string& ip)
|
||||
{
|
||||
return "implement me";
|
||||
}
|
||||
|
||||
/**
|
||||
* <20>жϸ<D0B6><CFB8><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP
|
||||
* @param ipAddress IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "192.168.1.1"<22><>
|
||||
* @return <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> IP<49><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD> true; <20><><EFBFBD><EFBFBD> false
|
||||
*/
|
||||
bool IsPrivateIP(const std::string& ipAddress) {
|
||||
// <20><> IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ
|
||||
in_addr addr;
|
||||
if (inet_pton(AF_INET, ipAddress.c_str(), &addr) != 1) {
|
||||
Mprintf("Invalid IP address: %s\n", ipAddress.c_str());
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* <20>жϸ<D0B6><CFB8><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP
|
||||
* @param ipAddress IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "192.168.1.1"<22><>
|
||||
* @return <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> IP<49><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD> true; <20><><EFBFBD><EFBFBD> false
|
||||
*/
|
||||
bool IsPrivateIP(const std::string& ipAddress)
|
||||
{
|
||||
// <20><> IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ
|
||||
in_addr addr;
|
||||
if (inet_pton(AF_INET, ipAddress.c_str(), &addr) != 1) {
|
||||
Mprintf("Invalid IP address: %s\n", ipAddress.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַת<D6B7><D7AA>Ϊ<EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
unsigned long ip = ntohl(addr.s_addr);
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַת<D6B7><D7AA>Ϊ<EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
unsigned long ip = ntohl(addr.s_addr);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>ھ<EFBFBD><DABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7>
|
||||
if ((ip >= 0x0A000000 && ip <= 0x0AFFFFFF) || // 10.0.0.0/8
|
||||
(ip >= 0xAC100000 && ip <= 0xAC1FFFFF) || // 172.16.0.0/12
|
||||
(ip >= 0xC0A80000 && ip <= 0xC0A8FFFF) || // 192.168.0.0/16
|
||||
(ip >= 0x7F000000 && ip <= 0x7FFFFFFF)) { // 127.0.0.0/8
|
||||
return true;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>ھ<EFBFBD><DABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7>
|
||||
if ((ip >= 0x0A000000 && ip <= 0x0AFFFFFF) || // 10.0.0.0/8
|
||||
(ip >= 0xAC100000 && ip <= 0xAC1FFFFF) || // 172.16.0.0/12
|
||||
(ip >= 0xC0A80000 && ip <= 0xC0A8FFFF) || // 192.168.0.0/16
|
||||
(ip >= 0x7F000000 && ip <= 0x7FFFFFFF)) { // 127.0.0.0/8
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
std::string GetLocalLocation() {
|
||||
return GetGeoLocation(getPublicIP());
|
||||
}
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
std::string GetLocalLocation()
|
||||
{
|
||||
return GetGeoLocation(getPublicIP());
|
||||
}
|
||||
|
||||
// <20><>ȡ IP <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>(<28><><EFBFBD><EFBFBD>[ipinfo.io])
|
||||
std::string GetGeoLocation(const std::string& IP) {
|
||||
if (IP.empty()) return "";
|
||||
// <20><>ȡ IP <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>(<28><><EFBFBD><EFBFBD>[ipinfo.io])
|
||||
std::string GetGeoLocation(const std::string& IP)
|
||||
{
|
||||
if (IP.empty()) return "";
|
||||
|
||||
std::string ip = IP;
|
||||
if (isLocalIP(ip)) {
|
||||
ip = getPublicIP();
|
||||
if (ip.empty())
|
||||
return "";
|
||||
}
|
||||
std::string ip = IP;
|
||||
if (isLocalIP(ip)) {
|
||||
ip = getPublicIP();
|
||||
if (ip.empty())
|
||||
return "";
|
||||
}
|
||||
|
||||
HINTERNET hInternet, hConnect;
|
||||
DWORD bytesRead;
|
||||
std::string readBuffer;
|
||||
HINTERNET hInternet, hConnect;
|
||||
DWORD bytesRead;
|
||||
std::string readBuffer;
|
||||
|
||||
// <20><>ʼ<EFBFBD><CABC> WinINet
|
||||
hInternet = InternetOpen("IP Geolocation", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||
if (hInternet == NULL) {
|
||||
Mprintf("InternetOpen failed! %d\n", GetLastError());
|
||||
return "";
|
||||
}
|
||||
// <20><>ʼ<EFBFBD><CABC> WinINet
|
||||
hInternet = InternetOpen("IP Geolocation", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||
if (hInternet == NULL) {
|
||||
Mprintf("InternetOpen failed! %d\n", GetLastError());
|
||||
return "";
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::string url = "http://ipinfo.io/" + ip + "/json";
|
||||
hConnect = InternetOpenUrlA(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);
|
||||
if (hConnect == NULL) {
|
||||
Mprintf("InternetOpenUrlA failed! %d\n", GetLastError());
|
||||
InternetCloseHandle(hInternet);
|
||||
return "";
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::string url = "http://ipinfo.io/" + ip + "/json";
|
||||
hConnect = InternetOpenUrlA(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);
|
||||
if (hConnect == NULL) {
|
||||
Mprintf("InternetOpenUrlA failed! %d\n", GetLastError());
|
||||
InternetCloseHandle(hInternet);
|
||||
return "";
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
char buffer[4096];
|
||||
while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
|
||||
readBuffer.append(buffer, bytesRead);
|
||||
}
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
char buffer[4096];
|
||||
while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
|
||||
readBuffer.append(buffer, bytesRead);
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> JSON <20><>Ӧ
|
||||
Json::Value jsonData;
|
||||
Json::Reader jsonReader;
|
||||
std::string location;
|
||||
// <20><><EFBFBD><EFBFBD> JSON <20><>Ӧ
|
||||
Json::Value jsonData;
|
||||
Json::Reader jsonReader;
|
||||
std::string location;
|
||||
|
||||
if (jsonReader.parse(readBuffer, jsonData)) {
|
||||
std::string country = jsonData["country"].asString();
|
||||
std::string city = jsonData["city"].asString();
|
||||
std::string loc = jsonData["loc"].asString(); // <20><>γ<EFBFBD><CEB3><EFBFBD><EFBFBD>Ϣ
|
||||
if (city.empty() && country.empty()) {
|
||||
}
|
||||
else if (city.empty()) {
|
||||
location = country;
|
||||
}
|
||||
else if (country.empty()) {
|
||||
location = city;
|
||||
}
|
||||
else {
|
||||
location = city + ", " + country;
|
||||
}
|
||||
if (location.empty() && IsPrivateIP(ip)) {
|
||||
location = "Local Area Network";
|
||||
}
|
||||
}
|
||||
else {
|
||||
Mprintf("Failed to parse JSON response: %s.\n", readBuffer.c_str());
|
||||
}
|
||||
if (jsonReader.parse(readBuffer, jsonData)) {
|
||||
std::string country = jsonData["country"].asString();
|
||||
std::string city = jsonData["city"].asString();
|
||||
std::string loc = jsonData["loc"].asString(); // <20><>γ<EFBFBD><CEB3><EFBFBD><EFBFBD>Ϣ
|
||||
if (city.empty() && country.empty()) {
|
||||
} else if (city.empty()) {
|
||||
location = country;
|
||||
} else if (country.empty()) {
|
||||
location = city;
|
||||
} else {
|
||||
location = city + ", " + country;
|
||||
}
|
||||
if (location.empty() && IsPrivateIP(ip)) {
|
||||
location = "Local Area Network";
|
||||
}
|
||||
} else {
|
||||
Mprintf("Failed to parse JSON response: %s.\n", readBuffer.c_str());
|
||||
}
|
||||
|
||||
// <20>رվ<D8B1><D5BE><EFBFBD>
|
||||
InternetCloseHandle(hConnect);
|
||||
InternetCloseHandle(hInternet);
|
||||
// <20>رվ<D8B1><D5BE><EFBFBD>
|
||||
InternetCloseHandle(hConnect);
|
||||
InternetCloseHandle(hInternet);
|
||||
|
||||
return location;
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
bool isLoopbackAddress(const std::string& ip) {
|
||||
return (ip == "127.0.0.1" || ip == "::1");
|
||||
}
|
||||
bool isLoopbackAddress(const std::string& ip)
|
||||
{
|
||||
return (ip == "127.0.0.1" || ip == "::1");
|
||||
}
|
||||
|
||||
bool isLocalIP(const std::string& ip) {
|
||||
if (isLoopbackAddress(ip)) return true; // <20>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD>ַ
|
||||
bool isLocalIP(const std::string& ip)
|
||||
{
|
||||
if (isLoopbackAddress(ip)) return true; // <20>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD>ַ
|
||||
|
||||
ULONG outBufLen = 15000;
|
||||
IP_ADAPTER_ADDRESSES* pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
|
||||
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
free(pAddresses);
|
||||
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
|
||||
}
|
||||
ULONG outBufLen = 15000;
|
||||
IP_ADAPTER_ADDRESSES* pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
|
||||
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
free(pAddresses);
|
||||
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
|
||||
}
|
||||
|
||||
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == NO_ERROR) {
|
||||
for (IP_ADAPTER_ADDRESSES* pCurrAddresses = pAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next) {
|
||||
for (IP_ADAPTER_UNICAST_ADDRESS* pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
|
||||
char addressBuffer[INET6_ADDRSTRLEN] = { 0 };
|
||||
getnameinfo(pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength, addressBuffer, sizeof(addressBuffer), nullptr, 0, NI_NUMERICHOST);
|
||||
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == NO_ERROR) {
|
||||
for (IP_ADAPTER_ADDRESSES* pCurrAddresses = pAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next) {
|
||||
for (IP_ADAPTER_UNICAST_ADDRESS* pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
|
||||
char addressBuffer[INET6_ADDRSTRLEN] = { 0 };
|
||||
getnameinfo(pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength, addressBuffer, sizeof(addressBuffer), nullptr, 0, NI_NUMERICHOST);
|
||||
|
||||
if (ip == addressBuffer) {
|
||||
free(pAddresses);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ip == addressBuffer) {
|
||||
free(pAddresses);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(pAddresses);
|
||||
return false;
|
||||
}
|
||||
free(pAddresses);
|
||||
return false;
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>IP, <20><>ȡʧ<C8A1>ܷ<EFBFBD><DCB7>ؿ<EFBFBD>
|
||||
std::string getPublicIP() {
|
||||
clock_t t = clock();
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>IP, <20><>ȡʧ<C8A1>ܷ<EFBFBD><DCB7>ؿ<EFBFBD>
|
||||
std::string getPublicIP()
|
||||
{
|
||||
clock_t t = clock();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ѯԴ
|
||||
static const std::vector<std::string> urls = {
|
||||
"https://checkip.amazonaws.com", // ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
"https://api.ipify.org", // <20><><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><DFBF><EFBFBD>
|
||||
"https://ipinfo.io/ip", // <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>
|
||||
"https://icanhazip.com", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
"https://ifconfig.me/ip" // ĩλ<C4A9><CEBB><EFBFBD><EFBFBD>
|
||||
};
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ѯԴ
|
||||
static const std::vector<std::string> urls = {
|
||||
"https://checkip.amazonaws.com", // ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
"https://api.ipify.org", // <20><><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><DFBF><EFBFBD>
|
||||
"https://ipinfo.io/ip", // <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>
|
||||
"https://icanhazip.com", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
"https://ifconfig.me/ip" // ĩλ<C4A9><CEBB><EFBFBD><EFBFBD>
|
||||
};
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> WinINet <20>Ự
|
||||
HINTERNET hInternet = InternetOpenA("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||
if (!hInternet) {
|
||||
Mprintf("InternetOpen failed. cost %d ms.\n", clock() - t);
|
||||
return "";
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD> WinINet <20>Ự
|
||||
HINTERNET hInternet = InternetOpenA("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||
if (!hInternet) {
|
||||
Mprintf("InternetOpen failed. cost %d ms.\n", clock() - t);
|
||||
return "";
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ó<EFBFBD>ʱ (<28><><EFBFBD><EFBFBD>)
|
||||
DWORD timeout = 3000; // 3 <20><>
|
||||
InternetSetOptionA(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout));
|
||||
InternetSetOptionA(hInternet, INTERNET_OPTION_SEND_TIMEOUT, &timeout, sizeof(timeout));
|
||||
InternetSetOptionA(hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &timeout, sizeof(timeout));
|
||||
// <20><><EFBFBD>ó<EFBFBD>ʱ (<28><><EFBFBD><EFBFBD>)
|
||||
DWORD timeout = 3000; // 3 <20><>
|
||||
InternetSetOptionA(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout));
|
||||
InternetSetOptionA(hInternet, INTERNET_OPTION_SEND_TIMEOUT, &timeout, sizeof(timeout));
|
||||
InternetSetOptionA(hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &timeout, sizeof(timeout));
|
||||
|
||||
std::string result;
|
||||
char buffer[2048];
|
||||
DWORD bytesRead = 0;
|
||||
std::string result;
|
||||
char buffer[2048];
|
||||
DWORD bytesRead = 0;
|
||||
|
||||
// <20><>ѯ<EFBFBD><D1AF>ͬ IP <20><>ѯԴ
|
||||
for (const auto& url : urls) {
|
||||
HINTERNET hConnect = InternetOpenUrlA(
|
||||
hInternet, url.c_str(), NULL, 0,
|
||||
INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE,
|
||||
0
|
||||
);
|
||||
// <20><>ѯ<EFBFBD><D1AF>ͬ IP <20><>ѯԴ
|
||||
for (const auto& url : urls) {
|
||||
HINTERNET hConnect = InternetOpenUrlA(
|
||||
hInternet, url.c_str(), NULL, 0,
|
||||
INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE,
|
||||
0
|
||||
);
|
||||
|
||||
if (!hConnect) {
|
||||
continue; // <20><>ǰԴʧ<D4B4>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
}
|
||||
if (!hConnect) {
|
||||
continue; // <20><>ǰԴʧ<D4B4>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||||
}
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
if (InternetReadFile(hConnect, buffer, sizeof(buffer) - 1, &bytesRead) && bytesRead > 0) {
|
||||
result.assign(buffer, bytesRead);
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
if (InternetReadFile(hConnect, buffer, sizeof(buffer) - 1, &bytesRead) && bytesRead > 0) {
|
||||
result.assign(buffer, bytesRead);
|
||||
|
||||
// ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7>Ϳո<CDBF>
|
||||
while (!result.empty() && (result.back() == '\n' || result.back() == '\r' || result.back() == ' '))
|
||||
result.pop_back();
|
||||
// ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7>Ϳո<CDBF>
|
||||
while (!result.empty() && (result.back() == '\n' || result.back() == '\r' || result.back() == ' '))
|
||||
result.pop_back();
|
||||
|
||||
InternetCloseHandle(hConnect);
|
||||
break; // <20>ɹ<EFBFBD><C9B9><EFBFBD>ȡ<EFBFBD><C8A1>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
|
||||
}
|
||||
InternetCloseHandle(hConnect);
|
||||
break; // <20>ɹ<EFBFBD><C9B9><EFBFBD>ȡ<EFBFBD><C8A1>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
InternetCloseHandle(hConnect);
|
||||
}
|
||||
InternetCloseHandle(hConnect);
|
||||
}
|
||||
|
||||
InternetCloseHandle(hInternet);
|
||||
InternetCloseHandle(hInternet);
|
||||
|
||||
Mprintf("getPublicIP %s cost %d ms.\n", result.empty() ? "failed" : "succeed", clock() - t);
|
||||
Mprintf("getPublicIP %s cost %d ms.\n", result.empty() ? "failed" : "succeed", clock() - t);
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
152
common/locker.h
152
common/locker.h
@@ -12,59 +12,60 @@ class CAutoLog
|
||||
{
|
||||
private:
|
||||
CRITICAL_SECTION *m_cs;
|
||||
const char* name;
|
||||
const char* name;
|
||||
public:
|
||||
CAutoLog(const char* _name, CRITICAL_SECTION *cs=NULL) : name(_name), m_cs(cs)
|
||||
{
|
||||
Mprintf(">>> Enter thread %s: [%d]\n", name ? name : "", GetCurrentThreadId());
|
||||
{
|
||||
Mprintf(">>> Enter thread %s: [%d]\n", name ? name : "", GetCurrentThreadId());
|
||||
if (m_cs)EnterCriticalSection(m_cs);
|
||||
}
|
||||
}
|
||||
|
||||
~CAutoLog()
|
||||
{
|
||||
~CAutoLog()
|
||||
{
|
||||
if (m_cs)LeaveCriticalSection(m_cs);
|
||||
Mprintf(">>> Leave thread %s: [%d]\n", name ? name : "", GetCurrentThreadId());
|
||||
}
|
||||
Mprintf(">>> Leave thread %s: [%d]\n", name ? name : "", GetCurrentThreadId());
|
||||
}
|
||||
};
|
||||
|
||||
class CLock {
|
||||
class CLock
|
||||
{
|
||||
public:
|
||||
CLock(CRITICAL_SECTION& cs) : m_cs(&cs)
|
||||
{
|
||||
Lock();
|
||||
}
|
||||
CLock() : m_cs(nullptr)
|
||||
{
|
||||
InitializeCriticalSection(&i_cs);
|
||||
}
|
||||
~CLock()
|
||||
{
|
||||
m_cs ? Unlock() : DeleteCriticalSection(&i_cs);
|
||||
}
|
||||
CLock(CRITICAL_SECTION& cs) : m_cs(&cs)
|
||||
{
|
||||
Lock();
|
||||
}
|
||||
CLock() : m_cs(nullptr)
|
||||
{
|
||||
InitializeCriticalSection(&i_cs);
|
||||
}
|
||||
~CLock()
|
||||
{
|
||||
m_cs ? Unlock() : DeleteCriticalSection(&i_cs);
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
LeaveCriticalSection(m_cs ? m_cs : &i_cs);
|
||||
}
|
||||
void Unlock()
|
||||
{
|
||||
LeaveCriticalSection(m_cs ? m_cs : &i_cs);
|
||||
}
|
||||
|
||||
void Lock()
|
||||
{
|
||||
EnterCriticalSection(m_cs ? m_cs : &i_cs);
|
||||
}
|
||||
void Lock()
|
||||
{
|
||||
EnterCriticalSection(m_cs ? m_cs : &i_cs);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
LeaveCriticalSection(m_cs ? m_cs : &i_cs);
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
LeaveCriticalSection(m_cs ? m_cs : &i_cs);
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
EnterCriticalSection(m_cs ? m_cs : &i_cs);
|
||||
}
|
||||
void lock()
|
||||
{
|
||||
EnterCriticalSection(m_cs ? m_cs : &i_cs);
|
||||
}
|
||||
|
||||
protected:
|
||||
CRITICAL_SECTION* m_cs; // 外部锁
|
||||
CRITICAL_SECTION i_cs; // 内部锁
|
||||
CRITICAL_SECTION* m_cs; // 外部锁
|
||||
CRITICAL_SECTION i_cs; // 内部锁
|
||||
};
|
||||
|
||||
typedef CLock CLocker;
|
||||
@@ -72,53 +73,58 @@ typedef CLock CLocker;
|
||||
class CAutoLock
|
||||
{
|
||||
private:
|
||||
CRITICAL_SECTION &m_cs;
|
||||
CRITICAL_SECTION &m_cs;
|
||||
|
||||
public:
|
||||
CAutoLock(CRITICAL_SECTION& cs) : m_cs(cs)
|
||||
{
|
||||
{
|
||||
EnterCriticalSection(&m_cs);
|
||||
}
|
||||
}
|
||||
|
||||
~CAutoLock()
|
||||
{
|
||||
~CAutoLock()
|
||||
{
|
||||
LeaveCriticalSection(&m_cs);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 智能计时器,计算函数的耗时
|
||||
class auto_tick {
|
||||
class auto_tick
|
||||
{
|
||||
private:
|
||||
const char* file;
|
||||
const char* func;
|
||||
int line;
|
||||
int span;
|
||||
clock_t tick;
|
||||
__inline clock_t now() const {
|
||||
return clock();
|
||||
}
|
||||
__inline int time() const {
|
||||
return now() - tick;
|
||||
}
|
||||
const char* file;
|
||||
const char* func;
|
||||
int line;
|
||||
int span;
|
||||
clock_t tick;
|
||||
__inline clock_t now() const
|
||||
{
|
||||
return clock();
|
||||
}
|
||||
__inline int time() const
|
||||
{
|
||||
return now() - tick;
|
||||
}
|
||||
|
||||
public:
|
||||
auto_tick(const char* file_name, const char* func_name, int line_no, int th = 5) :
|
||||
file(file_name), func(func_name), line(line_no), span(th), tick(now()) { }
|
||||
~auto_tick() {
|
||||
stop();
|
||||
}
|
||||
auto_tick(const char* file_name, const char* func_name, int line_no, int th = 5) :
|
||||
file(file_name), func(func_name), line(line_no), span(th), tick(now()) { }
|
||||
~auto_tick()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
__inline void stop() {
|
||||
if (span != 0) {
|
||||
int s(this->time());
|
||||
if (s > span) {
|
||||
char buf[1024];
|
||||
sprintf_s(buf, "%s(%d) : [%s] cost [%d]ms.\n", file, line, func, s);
|
||||
OutputDebugStringA(buf);
|
||||
}
|
||||
span = 0;
|
||||
}
|
||||
}
|
||||
__inline void stop()
|
||||
{
|
||||
if (span != 0) {
|
||||
int s(this->time());
|
||||
if (s > span) {
|
||||
char buf[1024];
|
||||
sprintf_s(buf, "%s(%d) : [%s] cost [%d]ms.\n", file, line, func, s);
|
||||
OutputDebugStringA(buf);
|
||||
}
|
||||
span = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
330
common/logger.h
330
common/logger.h
@@ -21,204 +21,222 @@
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
inline bool stringToBool(const std::string& str) {
|
||||
std::string lower = str;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
return (lower == "true" || lower == "1");
|
||||
inline bool stringToBool(const std::string& str)
|
||||
{
|
||||
std::string lower = str;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
return (lower == "true" || lower == "1");
|
||||
}
|
||||
|
||||
class Logger {
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
enum LogLevel {
|
||||
InfoLevel, WarningLevel, ErrorLevel
|
||||
};
|
||||
enum LogLevel {
|
||||
InfoLevel, WarningLevel, ErrorLevel
|
||||
};
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ģʽ
|
||||
static Logger& getInstance() {
|
||||
static Logger instance;
|
||||
if (instance.pid.empty()) {
|
||||
char buf[16] = {};
|
||||
sprintf_s(buf, "%d", GetCurrentProcessId());
|
||||
instance.pid = buf;
|
||||
instance.InitLogFile("C:\\Windows\\Temp", instance.pid);
|
||||
// <20><><EFBFBD><EFBFBD>ģʽ
|
||||
static Logger& getInstance()
|
||||
{
|
||||
static Logger instance;
|
||||
if (instance.pid.empty()) {
|
||||
char buf[16] = {};
|
||||
sprintf_s(buf, "%d", GetCurrentProcessId());
|
||||
instance.pid = buf;
|
||||
instance.InitLogFile("C:\\Windows\\Temp", instance.pid);
|
||||
#ifdef _WINDOWS
|
||||
instance.enable = true; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־Ĭ<D6BE>ϴ<EFBFBD><CFB4><EFBFBD>
|
||||
instance.enable = true; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־Ĭ<D6BE>ϴ<EFBFBD><CFB4><EFBFBD>
|
||||
#else
|
||||
char var[32] = {};
|
||||
const char* name = skCrypt("ENABLE_LOG");
|
||||
DWORD size = GetEnvironmentVariableA(name, var, sizeof(var));
|
||||
instance.enable = stringToBool(var);
|
||||
instance.log("logger.h", __LINE__, "GetEnvironmentVariable: %s=%s\n", name, var);
|
||||
char var[32] = {};
|
||||
const char* name = skCrypt("ENABLE_LOG");
|
||||
DWORD size = GetEnvironmentVariableA(name, var, sizeof(var));
|
||||
instance.enable = stringToBool(var);
|
||||
instance.log("logger.h", __LINE__, "GetEnvironmentVariable: %s=%s\n", name, var);
|
||||
#endif
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
// <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||
Logger(const Logger&) = delete;
|
||||
Logger& operator=(const Logger&) = delete;
|
||||
// <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||
Logger(const Logger&) = delete;
|
||||
Logger& operator=(const Logger&) = delete;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
void setLogFile(const std::string& filename) {
|
||||
std::lock_guard<std::mutex> lock(fileMutex);
|
||||
logFileName = filename;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
void setLogFile(const std::string& filename)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fileMutex);
|
||||
logFileName = filename;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||||
void usingLog(bool b = true) {
|
||||
enable = b;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||||
void usingLog(bool b = true)
|
||||
{
|
||||
enable = b;
|
||||
}
|
||||
|
||||
// д<><D0B4>־<EFBFBD><D6BE>֧<EFBFBD><D6A7> printf <20><>ʽ<EFBFBD><CABD>
|
||||
void log(const char* file, int line, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
// д<><D0B4>־<EFBFBD><D6BE>֧<EFBFBD><D6A7> printf <20><>ʽ<EFBFBD><CABD>
|
||||
void log(const char* file, int line, const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
std::string message = formatString(format, args);
|
||||
std::string message = formatString(format, args);
|
||||
|
||||
va_end(args);
|
||||
va_end(args);
|
||||
|
||||
auto timestamp = getCurrentTimestamp();
|
||||
std::string id = pid.empty() ? "" : "[" + pid + "]";
|
||||
auto timestamp = getCurrentTimestamp();
|
||||
std::string id = pid.empty() ? "" : "[" + pid + "]";
|
||||
|
||||
std::string logEntry = id + "[" + timestamp + "] [" + file + ":" + std::to_string(line) + "] " + message;
|
||||
if (enable)
|
||||
{
|
||||
if (running) {
|
||||
std::lock_guard<std::mutex> lock(queueMutex);
|
||||
logQueue.push(logEntry);
|
||||
} else {
|
||||
writeToFile(logEntry);
|
||||
}
|
||||
}
|
||||
std::string logEntry = id + "[" + timestamp + "] [" + file + ":" + std::to_string(line) + "] " + message;
|
||||
if (enable) {
|
||||
if (running) {
|
||||
std::lock_guard<std::mutex> lock(queueMutex);
|
||||
logQueue.push(logEntry);
|
||||
} else {
|
||||
writeToFile(logEntry);
|
||||
}
|
||||
}
|
||||
#ifndef _WINDOWS
|
||||
#ifdef _DEBUG
|
||||
printf(logEntry.c_str());
|
||||
printf(logEntry.c_str());
|
||||
#endif
|
||||
#endif
|
||||
cv.notify_one(); // ֪ͨд<D6AA>߳<EFBFBD>
|
||||
}
|
||||
cv.notify_one(); // ֪ͨд<D6AA>߳<EFBFBD>
|
||||
}
|
||||
|
||||
// ֹͣ<CDA3><D6B9>־ϵͳ
|
||||
void stop() {
|
||||
if (!running) return;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(queueMutex);
|
||||
running = false; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
|
||||
}
|
||||
cv.notify_one();
|
||||
if (workerThread.joinable()) {
|
||||
workerThread.join();
|
||||
}
|
||||
for (int i = 0; threadRun && i++ < 1000; Sleep(1));
|
||||
}
|
||||
// ֹͣ<CDA3><D6B9>־ϵͳ
|
||||
void stop()
|
||||
{
|
||||
if (!running) return;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(queueMutex);
|
||||
running = false; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
|
||||
}
|
||||
cv.notify_one();
|
||||
if (workerThread.joinable()) {
|
||||
workerThread.join();
|
||||
}
|
||||
for (int i = 0; threadRun && i++ < 1000; Sleep(1));
|
||||
}
|
||||
|
||||
private:
|
||||
// <20><>־<EFBFBD><D6BE><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
void InitLogFile(const std::string & dir, const std::string& pid) {
|
||||
time_t currentTime = time(nullptr);
|
||||
tm* localTime = localtime(¤tTime);
|
||||
char timeString[32];
|
||||
strftime(timeString, sizeof(timeString), "%Y-%m", localTime);
|
||||
char fileName[100];
|
||||
// <20><>־<EFBFBD><D6BE><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
void InitLogFile(const std::string & dir, const std::string& pid)
|
||||
{
|
||||
time_t currentTime = time(nullptr);
|
||||
tm* localTime = localtime(¤tTime);
|
||||
char timeString[32];
|
||||
strftime(timeString, sizeof(timeString), "%Y-%m", localTime);
|
||||
char fileName[100];
|
||||
#ifdef _WINDOWS
|
||||
sprintf_s(fileName, "\\YAMA_%s_%s.txt", timeString, pid.c_str());
|
||||
sprintf_s(fileName, "\\YAMA_%s_%s.txt", timeString, pid.c_str());
|
||||
#else
|
||||
sprintf_s(fileName, "\\log_%s_%s.txt", timeString, pid.c_str());
|
||||
sprintf_s(fileName, "\\log_%s_%s.txt", timeString, pid.c_str());
|
||||
#endif
|
||||
logFileName = dir + fileName;
|
||||
}
|
||||
std::string logFileName; // <20><>־<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
bool enable; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
bool threadRun; // <20><>־<EFBFBD>߳<EFBFBD>״̬
|
||||
std::queue<std::string> logQueue; // <20><>־<EFBFBD><D6BE><EFBFBD><EFBFBD>
|
||||
std::mutex queueMutex; // <20><><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::condition_variable cv; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::atomic<bool> running; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::thread workerThread; // <20><>̨<EFBFBD>߳<EFBFBD>
|
||||
std::mutex fileMutex; // <20>ļ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
|
||||
std::string pid; // <20><><EFBFBD><EFBFBD>ID
|
||||
logFileName = dir + fileName;
|
||||
}
|
||||
std::string logFileName; // <20><>־<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
bool enable; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
bool threadRun; // <20><>־<EFBFBD>߳<EFBFBD>״̬
|
||||
std::queue<std::string> logQueue; // <20><>־<EFBFBD><D6BE><EFBFBD><EFBFBD>
|
||||
std::mutex queueMutex; // <20><><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::condition_variable cv; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::atomic<bool> running; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::thread workerThread; // <20><>̨<EFBFBD>߳<EFBFBD>
|
||||
std::mutex fileMutex; // <20>ļ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
|
||||
std::string pid; // <20><><EFBFBD><EFBFBD>ID
|
||||
|
||||
Logger() : enable(false), threadRun(false), running(true), workerThread(&Logger::processLogs, this) {}
|
||||
Logger() : enable(false), threadRun(false), running(true), workerThread(&Logger::processLogs, this) {}
|
||||
|
||||
~Logger() {
|
||||
stop();
|
||||
}
|
||||
~Logger()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
// <20><>̨<EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD>־
|
||||
void processLogs() {
|
||||
threadRun = true;
|
||||
while (running) {
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
cv.wait(lock, [this]() {
|
||||
return !running || !logQueue.empty();
|
||||
});
|
||||
// <20><>̨<EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD>־
|
||||
void processLogs()
|
||||
{
|
||||
threadRun = true;
|
||||
while (running) {
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
cv.wait(lock, [this]() {
|
||||
return !running || !logQueue.empty();
|
||||
});
|
||||
|
||||
while (running && !logQueue.empty()) {
|
||||
std::string logEntry = logQueue.front();
|
||||
logQueue.pop();
|
||||
lock.unlock();
|
||||
while (running && !logQueue.empty()) {
|
||||
std::string logEntry = logQueue.front();
|
||||
logQueue.pop();
|
||||
lock.unlock();
|
||||
|
||||
// д<><D0B4><EFBFBD><EFBFBD>־<EFBFBD>ļ<EFBFBD>
|
||||
writeToFile(logEntry);
|
||||
// д<><D0B4><EFBFBD><EFBFBD>־<EFBFBD>ļ<EFBFBD>
|
||||
writeToFile(logEntry);
|
||||
|
||||
lock.lock();
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
threadRun = false;
|
||||
}
|
||||
lock.lock();
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
threadRun = false;
|
||||
}
|
||||
|
||||
// д<><D0B4><EFBFBD>ļ<EFBFBD>
|
||||
void writeToFile(const std::string& logEntry) {
|
||||
std::lock_guard<std::mutex> lock(fileMutex);
|
||||
std::ofstream logFile(logFileName, std::ios::app);
|
||||
if (logFile.is_open()) {
|
||||
logFile << logEntry << std::endl;
|
||||
}
|
||||
}
|
||||
// д<><D0B4><EFBFBD>ļ<EFBFBD>
|
||||
void writeToFile(const std::string& logEntry)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fileMutex);
|
||||
std::ofstream logFile(logFileName, std::ios::app);
|
||||
if (logFile.is_open()) {
|
||||
logFile << logEntry << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1>ǰʱ<C7B0><CAB1><EFBFBD><EFBFBD>
|
||||
std::string getCurrentTimestamp() {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto in_time_t = std::chrono::system_clock::to_time_t(now);
|
||||
// <20><>ȡ<EFBFBD><C8A1>ǰʱ<C7B0><CAB1><EFBFBD><EFBFBD>
|
||||
std::string getCurrentTimestamp()
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto in_time_t = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
std::tm tm;
|
||||
std::tm tm;
|
||||
#ifdef _WIN32
|
||||
localtime_s(&tm, &in_time_t); // Windows <20><>ȫ<EFBFBD>汾
|
||||
localtime_s(&tm, &in_time_t); // Windows <20><>ȫ<EFBFBD>汾
|
||||
#else
|
||||
localtime_r(&in_time_t, &tm); // POSIX <20><>ȫ<EFBFBD>汾
|
||||
localtime_r(&in_time_t, &tm); // POSIX <20><>ȫ<EFBFBD>汾
|
||||
#endif
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
|
||||
return ss.str();
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
std::string logLevelToString(LogLevel level) {
|
||||
switch (level) {
|
||||
case InfoLevel: return "INFO";
|
||||
case WarningLevel: return "WARNING";
|
||||
case ErrorLevel: return "ERROR";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
std::string logLevelToString(LogLevel level)
|
||||
{
|
||||
switch (level) {
|
||||
case InfoLevel:
|
||||
return "INFO";
|
||||
case WarningLevel:
|
||||
return "WARNING";
|
||||
case ErrorLevel:
|
||||
return "ERROR";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
// <20><>ʽ<EFBFBD><CABD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
std::string formatString(const char* format, va_list args) {
|
||||
char buffer[1024];
|
||||
vsnprintf(buffer, sizeof(buffer), format, args);
|
||||
return std::string(buffer);
|
||||
}
|
||||
// <20><>ʽ<EFBFBD><CABD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
std::string formatString(const char* format, va_list args)
|
||||
{
|
||||
char buffer[1024];
|
||||
vsnprintf(buffer, sizeof(buffer), format, args);
|
||||
return std::string(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
inline const char* getFileName(const char* path) {
|
||||
const char* fileName = strrchr(path, '\\');
|
||||
if (!fileName) {
|
||||
fileName = strrchr(path, '/');
|
||||
}
|
||||
return fileName ? fileName + 1 : path;
|
||||
inline const char* getFileName(const char* path)
|
||||
{
|
||||
const char* fileName = strrchr(path, '\\');
|
||||
if (!fileName) {
|
||||
fileName = strrchr(path, '/');
|
||||
}
|
||||
return fileName ? fileName + 1 : path;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
115
common/mask.h
115
common/mask.h
@@ -5,79 +5,92 @@
|
||||
// 数据包协议封装格式
|
||||
// Copy left: 962914132@qq.com & ChatGPT
|
||||
enum PkgMaskType {
|
||||
MaskTypeUnknown = -1,
|
||||
MaskTypeNone,
|
||||
MaskTypeHTTP,
|
||||
MaskTypeNum,
|
||||
MaskTypeUnknown = -1,
|
||||
MaskTypeNone,
|
||||
MaskTypeHTTP,
|
||||
MaskTypeNum,
|
||||
};
|
||||
|
||||
#define DEFAULT_HOST "example.com"
|
||||
|
||||
inline ULONG UnMaskHttp(char* src, ULONG srcSize) {
|
||||
const char* header_end_mark = "\r\n\r\n";
|
||||
const ULONG mark_len = 4;
|
||||
inline ULONG UnMaskHttp(char* src, ULONG srcSize)
|
||||
{
|
||||
const char* header_end_mark = "\r\n\r\n";
|
||||
const ULONG mark_len = 4;
|
||||
|
||||
// 查找 HTTP 头部结束标记
|
||||
for (ULONG i = 0; i + mark_len <= srcSize; ++i) {
|
||||
if (memcmp(src + i, header_end_mark, mark_len) == 0) {
|
||||
return i + mark_len; // 返回 Body 起始位置
|
||||
}
|
||||
}
|
||||
return 0; // 无效数据
|
||||
// 查找 HTTP 头部结束标记
|
||||
for (ULONG i = 0; i + mark_len <= srcSize; ++i) {
|
||||
if (memcmp(src + i, header_end_mark, mark_len) == 0) {
|
||||
return i + mark_len; // 返回 Body 起始位置
|
||||
}
|
||||
}
|
||||
return 0; // 无效数据
|
||||
}
|
||||
|
||||
// TryUnMask 尝试去掉伪装的协议头.
|
||||
inline ULONG TryUnMask(char* src, ULONG srcSize, PkgMaskType& maskHit) {
|
||||
if (srcSize >= 5 && memcmp(src, "POST ", 5) == 0) {
|
||||
maskHit = MaskTypeHTTP;
|
||||
return UnMaskHttp(src, srcSize);
|
||||
}
|
||||
maskHit = MaskTypeNone;
|
||||
return 0;
|
||||
inline ULONG TryUnMask(char* src, ULONG srcSize, PkgMaskType& maskHit)
|
||||
{
|
||||
if (srcSize >= 5 && memcmp(src, "POST ", 5) == 0) {
|
||||
maskHit = MaskTypeHTTP;
|
||||
return UnMaskHttp(src, srcSize);
|
||||
}
|
||||
maskHit = MaskTypeNone;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// PkgMask 针对消息进一步加密、混淆或伪装.
|
||||
class PkgMask {
|
||||
class PkgMask
|
||||
{
|
||||
protected:
|
||||
virtual ~PkgMask() {}
|
||||
public:
|
||||
virtual void Destroy() {
|
||||
virtual void Destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
virtual void Mask(char*& dst, ULONG& dstSize, char* src, ULONG srcSize, int cmd = -1) {
|
||||
virtual void Mask(char*& dst, ULONG& dstSize, char* src, ULONG srcSize, int cmd = -1)
|
||||
{
|
||||
dst = src;
|
||||
dstSize = srcSize;
|
||||
}
|
||||
virtual ULONG UnMask(char* src, ULONG srcSize) {
|
||||
virtual ULONG UnMask(char* src, ULONG srcSize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual PkgMask* SetServer(const std::string& addr) { return this; }
|
||||
virtual PkgMaskType GetMaskType() const {
|
||||
virtual PkgMask* SetServer(const std::string& addr)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
virtual PkgMaskType GetMaskType() const
|
||||
{
|
||||
return MaskTypeNone;
|
||||
}
|
||||
};
|
||||
|
||||
class HttpMask : public PkgMask {
|
||||
class HttpMask : public PkgMask
|
||||
{
|
||||
public:
|
||||
virtual PkgMaskType GetMaskType() const override {
|
||||
return MaskTypeHTTP;
|
||||
}
|
||||
virtual PkgMaskType GetMaskType() const override
|
||||
{
|
||||
return MaskTypeHTTP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 构造函数
|
||||
* @param host HTTP Host 头字段
|
||||
*/
|
||||
explicit HttpMask(const std::string& host, const std::map<std::string, std::string>& headers = {}) :
|
||||
product_(GenerateRandomString()), host_(host) {
|
||||
explicit HttpMask(const std::string& host, const std::map<std::string, std::string>& headers = {}) :
|
||||
product_(GenerateRandomString()), host_(host)
|
||||
{
|
||||
// 初始化随机数生成器
|
||||
srand(static_cast<unsigned>(time(nullptr)));
|
||||
char buf[32];
|
||||
sprintf_s(buf, "V%d.%d.%d", rand() % 10, rand() % 10, rand() % 10);
|
||||
version_ = buf;
|
||||
user_agent_ = GetEnhancedSystemUA(product_, version_);
|
||||
for (std::map<std::string, std::string>::const_iterator it = headers.begin(); it != headers.end(); ++it) {
|
||||
for (std::map<std::string, std::string>::const_iterator it = headers.begin(); it != headers.end(); ++it) {
|
||||
headers_ += it->first + ": " + it->second + "\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +101,8 @@ public:
|
||||
* @param srcSize 原始数据长度
|
||||
* @param cmd 命令号
|
||||
*/
|
||||
void Mask(char*& dst, ULONG& dstSize, char* src, ULONG srcSize, int cmd = -1) {
|
||||
void Mask(char*& dst, ULONG& dstSize, char* src, ULONG srcSize, int cmd = -1)
|
||||
{
|
||||
// 生成动态 HTTP 头部
|
||||
std::string http_header =
|
||||
"POST " + GeneratePath(cmd) + " HTTP/1.1\r\n"
|
||||
@@ -114,16 +128,19 @@ public:
|
||||
* @param srcSize 数据长度
|
||||
* @return ULONG 原始数据在 src 中的起始偏移量(失败返回 0)
|
||||
*/
|
||||
ULONG UnMask(char* src, ULONG srcSize) {
|
||||
ULONG UnMask(char* src, ULONG srcSize)
|
||||
{
|
||||
return UnMaskHttp(src, srcSize);
|
||||
}
|
||||
|
||||
PkgMask* SetServer(const std::string& addr) override {
|
||||
PkgMask* SetServer(const std::string& addr) override
|
||||
{
|
||||
host_ = addr;
|
||||
return this;
|
||||
}
|
||||
private:
|
||||
static std::string GetEnhancedSystemUA(const std::string& appName, const std::string& appVersion) {
|
||||
static std::string GetEnhancedSystemUA(const std::string& appName, const std::string& appVersion)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
OSVERSIONINFOEX osvi = {};
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
@@ -133,15 +150,15 @@ private:
|
||||
SYSTEM_INFO si;
|
||||
GetNativeSystemInfo(&si);
|
||||
std::string arch = (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ? "Win64; x64" :
|
||||
(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64) ? "Win64; ARM64" :
|
||||
"WOW64";
|
||||
(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64) ? "Win64; ARM64" :
|
||||
"WOW64";
|
||||
|
||||
return "Mozilla/5.0 (" +
|
||||
std::string("Windows NT ") +
|
||||
std::to_string(osvi.dwMajorVersion) + "." +
|
||||
std::to_string(osvi.dwMinorVersion) + "; " +
|
||||
arch + ") " +
|
||||
appName + "/" + appVersion;
|
||||
std::string("Windows NT ") +
|
||||
std::to_string(osvi.dwMajorVersion) + "." +
|
||||
std::to_string(osvi.dwMinorVersion) + "; " +
|
||||
arch + ") " +
|
||||
appName + "/" + appVersion;
|
||||
#else
|
||||
return "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36";
|
||||
#endif
|
||||
@@ -154,7 +171,8 @@ private:
|
||||
std::string headers_; // 自定义请求头
|
||||
|
||||
/** 生成随机 URL 路径 */
|
||||
std::string GenerateRandomString(int size = 8) const {
|
||||
std::string GenerateRandomString(int size = 8) const
|
||||
{
|
||||
static const char charset[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
char path[32];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
@@ -163,7 +181,8 @@ private:
|
||||
path[size] = 0;
|
||||
return path;
|
||||
}
|
||||
std::string GeneratePath(int cmd) const {
|
||||
std::string GeneratePath(int cmd) const
|
||||
{
|
||||
static std::string root = "/" + product_ + "/" + GenerateRandomString() + "/";
|
||||
return root + (cmd == -1 ? GenerateRandomString() : std::to_string(cmd));
|
||||
}
|
||||
|
||||
61
common/md5.h
61
common/md5.h
@@ -2,41 +2,42 @@
|
||||
|
||||
#include <wincrypt.h>
|
||||
|
||||
inline std::string CalcMD5FromBytes(const BYTE* data, DWORD length) {
|
||||
HCRYPTPROV hProv = 0;
|
||||
HCRYPTHASH hHash = 0;
|
||||
BYTE hash[16]; // MD5 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 16 <20>ֽ<EFBFBD>
|
||||
DWORD hashLen = sizeof(hash);
|
||||
std::ostringstream oss;
|
||||
inline std::string CalcMD5FromBytes(const BYTE* data, DWORD length)
|
||||
{
|
||||
HCRYPTPROV hProv = 0;
|
||||
HCRYPTHASH hHash = 0;
|
||||
BYTE hash[16]; // MD5 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 16 <20>ֽ<EFBFBD>
|
||||
DWORD hashLen = sizeof(hash);
|
||||
std::ostringstream oss;
|
||||
|
||||
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||
return "";
|
||||
}
|
||||
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return "";
|
||||
}
|
||||
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!CryptHashData(hHash, data, length, 0)) {
|
||||
CryptDestroyHash(hHash);
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return "";
|
||||
}
|
||||
if (!CryptHashData(hHash, data, length, 0)) {
|
||||
CryptDestroyHash(hHash);
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!CryptGetHashParam(hHash, HP_HASHVAL, hash, &hashLen, 0)) {
|
||||
CryptDestroyHash(hHash);
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return "";
|
||||
}
|
||||
if (!CryptGetHashParam(hHash, HP_HASHVAL, hash, &hashLen, 0)) {
|
||||
CryptDestroyHash(hHash);
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return "";
|
||||
}
|
||||
|
||||
// ת<><D7AA>Ϊʮ<CEAA><CAAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
for (DWORD i = 0; i < hashLen; ++i) {
|
||||
oss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
|
||||
}
|
||||
// ת<><D7AA>Ϊʮ<CEAA><CAAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
for (DWORD i = 0; i < hashLen; ++i) {
|
||||
oss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
|
||||
}
|
||||
|
||||
CryptDestroyHash(hHash);
|
||||
CryptReleaseContext(hProv, 0);
|
||||
CryptDestroyHash(hHash);
|
||||
CryptReleaseContext(hProv, 0);
|
||||
|
||||
return oss.str();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
72
common/obfs.h
Normal file
72
common/obfs.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#pragma once
|
||||
|
||||
class ObfsBase {
|
||||
public:
|
||||
// <20>Գƻ<D4B3><C6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><DABC>ܺͽ<DCBA><CDBD><EFBFBD>
|
||||
virtual void ObfuscateBuffer(uint8_t* buf, size_t len, uint32_t seed) {}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD>෴
|
||||
virtual void DeobfuscateBuffer(uint8_t* buf, size_t len, uint32_t seed) {}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> C <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽд<CABD><D0B4><EFBFBD>ļ<EFBFBD>
|
||||
virtual bool WriteBinaryAsCArray(const char* filename, uint8_t* data, size_t length, const char* arrayName) {
|
||||
FILE* file = fopen(filename, "w");
|
||||
if (!file) return false;
|
||||
|
||||
fprintf(file, "unsigned char %s[] = {\n", arrayName);
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
if (i % 24 == 0) fprintf(file, " ");
|
||||
fprintf(file, "0x%02X", data[i]);
|
||||
if (i != length - 1) fprintf(file, ",");
|
||||
if ((i + 1) % 24 == 0 || i == length - 1) fprintf(file, "\n");
|
||||
else fprintf(file, " ");
|
||||
}
|
||||
fprintf(file, "};\n");
|
||||
fprintf(file, "unsigned int %s_len = %zu;\n", arrayName, length);
|
||||
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class Obfs : public ObfsBase {
|
||||
private:
|
||||
// <20><><EFBFBD><EFBFBD>8λ<38><CEBB><EFBFBD><EFBFBD>
|
||||
static inline uint8_t rol8(uint8_t val, int shift) {
|
||||
return (val << shift) | (val >> (8 - shift));
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>8λ<38><CEBB><EFBFBD><EFBFBD>
|
||||
static inline uint8_t ror8(uint8_t val, int shift) {
|
||||
return (val >> shift) | (val << (8 - shift));
|
||||
}
|
||||
|
||||
public:
|
||||
// <20>Գƻ<D4B3><C6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><DABC>ܺͽ<DCBA><CDBD><EFBFBD>
|
||||
virtual void ObfuscateBuffer(uint8_t* buf, size_t len, uint32_t seed) {
|
||||
uint32_t state = seed;
|
||||
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
uint8_t mask = (uint8_t)((state >> 16) & 0xFF);
|
||||
buf[i] = rol8(buf[i] ^ mask, 3); // <20><><EFBFBD><EFBFBD>+<2B><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
state = state * 2654435761u + buf[i]; // LCG + <20><><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD>෴
|
||||
virtual void DeobfuscateBuffer(uint8_t* buf, size_t len, uint32_t seed) {
|
||||
uint32_t state = seed;
|
||||
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
uint8_t mask = (uint8_t)((state >> 16) & 0xFF);
|
||||
uint8_t orig = buf[i];
|
||||
buf[i] = ror8(buf[i], 3) ^ mask;
|
||||
state = state * 2654435761u + orig; // <20><><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD>ǰ<EFBFBD><C7B0>ԭ<EFBFBD>ֽڸ<D6BD><DAB8><EFBFBD> state
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -13,121 +13,118 @@ skCrypter
|
||||
____________________________________________________________________________________________________________*/
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
namespace std
|
||||
{
|
||||
// STRUCT TEMPLATE remove_reference
|
||||
template <class _Ty>
|
||||
struct remove_reference {
|
||||
using type = _Ty;
|
||||
};
|
||||
namespace std
|
||||
{
|
||||
// STRUCT TEMPLATE remove_reference
|
||||
template <class _Ty>
|
||||
struct remove_reference {
|
||||
using type = _Ty;
|
||||
};
|
||||
|
||||
template <class _Ty>
|
||||
struct remove_reference<_Ty&> {
|
||||
using type = _Ty;
|
||||
};
|
||||
template <class _Ty>
|
||||
struct remove_reference<_Ty&> {
|
||||
using type = _Ty;
|
||||
};
|
||||
|
||||
template <class _Ty>
|
||||
struct remove_reference<_Ty&&> {
|
||||
using type = _Ty;
|
||||
};
|
||||
template <class _Ty>
|
||||
struct remove_reference<_Ty&&> {
|
||||
using type = _Ty;
|
||||
};
|
||||
|
||||
template <class _Ty>
|
||||
using remove_reference_t = typename remove_reference<_Ty>::type;
|
||||
template <class _Ty>
|
||||
using remove_reference_t = typename remove_reference<_Ty>::type;
|
||||
|
||||
// STRUCT TEMPLATE remove_const
|
||||
template <class _Ty>
|
||||
struct remove_const { // remove top-level const qualifier
|
||||
using type = _Ty;
|
||||
};
|
||||
// STRUCT TEMPLATE remove_const
|
||||
template <class _Ty>
|
||||
struct remove_const { // remove top-level const qualifier
|
||||
using type = _Ty;
|
||||
};
|
||||
|
||||
template <class _Ty>
|
||||
struct remove_const<const _Ty> {
|
||||
using type = _Ty;
|
||||
};
|
||||
template <class _Ty>
|
||||
struct remove_const<const _Ty> {
|
||||
using type = _Ty;
|
||||
};
|
||||
|
||||
template <class _Ty>
|
||||
using remove_const_t = typename remove_const<_Ty>::type;
|
||||
}
|
||||
template <class _Ty>
|
||||
using remove_const_t = typename remove_const<_Ty>::type;
|
||||
}
|
||||
#else
|
||||
#include <type_traits>
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace skc
|
||||
{
|
||||
template<class _Ty>
|
||||
using clean_type = typename std::remove_const_t<std::remove_reference_t<_Ty>>;
|
||||
template<class _Ty>
|
||||
using clean_type = typename std::remove_const_t<std::remove_reference_t<_Ty>>;
|
||||
|
||||
template <int _size, char _key1, char _key2, typename T>
|
||||
class skCrypter
|
||||
{
|
||||
public:
|
||||
__forceinline constexpr skCrypter(T* data)
|
||||
{
|
||||
crypt(data);
|
||||
}
|
||||
template <int _size, char _key1, char _key2, typename T>
|
||||
class skCrypter {
|
||||
public:
|
||||
__forceinline constexpr skCrypter(T* data)
|
||||
{
|
||||
crypt(data);
|
||||
}
|
||||
|
||||
__forceinline T* get()
|
||||
{
|
||||
return _storage;
|
||||
}
|
||||
__forceinline T* get()
|
||||
{
|
||||
return _storage;
|
||||
}
|
||||
|
||||
__forceinline int size() // (w)char count
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
__forceinline int size() // (w)char count
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
__forceinline char key()
|
||||
{
|
||||
return _key1;
|
||||
}
|
||||
__forceinline char key()
|
||||
{
|
||||
return _key1;
|
||||
}
|
||||
|
||||
__forceinline T* encrypt()
|
||||
{
|
||||
if (!isEncrypted())
|
||||
crypt(_storage);
|
||||
__forceinline T* encrypt()
|
||||
{
|
||||
if (!isEncrypted())
|
||||
crypt(_storage);
|
||||
|
||||
return _storage;
|
||||
}
|
||||
return _storage;
|
||||
}
|
||||
|
||||
__forceinline T* decrypt()
|
||||
{
|
||||
if (isEncrypted())
|
||||
crypt(_storage);
|
||||
__forceinline T* decrypt()
|
||||
{
|
||||
if (isEncrypted())
|
||||
crypt(_storage);
|
||||
|
||||
return _storage;
|
||||
}
|
||||
return _storage;
|
||||
}
|
||||
|
||||
__forceinline bool isEncrypted()
|
||||
{
|
||||
return _storage[_size - 1] != 0;
|
||||
}
|
||||
__forceinline bool isEncrypted()
|
||||
{
|
||||
return _storage[_size - 1] != 0;
|
||||
}
|
||||
|
||||
__forceinline void clear() // set full storage to 0
|
||||
{
|
||||
for (int i = 0; i < _size; i++)
|
||||
{
|
||||
_storage[i] = 0;
|
||||
}
|
||||
}
|
||||
__forceinline void clear() // set full storage to 0
|
||||
{
|
||||
for (int i = 0; i < _size; i++) {
|
||||
_storage[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline operator T* ()
|
||||
{
|
||||
decrypt();
|
||||
__forceinline operator T* ()
|
||||
{
|
||||
decrypt();
|
||||
|
||||
return _storage;
|
||||
}
|
||||
|
||||
private:
|
||||
__forceinline constexpr void crypt(T* data)
|
||||
{
|
||||
for (int i = 0; i < _size; i++)
|
||||
{
|
||||
_storage[i] = data[i] ^ (_key1 + i % (1 + _key2));
|
||||
}
|
||||
}
|
||||
return _storage;
|
||||
}
|
||||
|
||||
T _storage[_size]{};
|
||||
};
|
||||
private:
|
||||
__forceinline constexpr void crypt(T* data)
|
||||
{
|
||||
for (int i = 0; i < _size; i++) {
|
||||
_storage[i] = data[i] ^ (_key1 + i % (1 + _key2));
|
||||
}
|
||||
}
|
||||
|
||||
T _storage[_size]{};
|
||||
};
|
||||
}
|
||||
|
||||
#define skCrypt(str) skCrypt_key(str, __TIME__[4], __TIME__[7])
|
||||
|
||||
171
common/wallet.h
171
common/wallet.h
@@ -5,101 +5,116 @@
|
||||
// Powered by ChatGPT.
|
||||
|
||||
enum WalletType {
|
||||
WALLET_UNKNOWN = 0,
|
||||
WALLET_BTC_P2PKH,
|
||||
WALLET_BTC_P2SH,
|
||||
WALLET_BTC_BECH32,
|
||||
WALLET_ETH_ERC20, // ETH、ERC20(含 USDT-ERC20)
|
||||
WALLET_USDT_OMNI, // USDT Omni,BTC 网络,格式同 BTC
|
||||
WALLET_USDT_TRC20, // USDT TRC20
|
||||
WALLET_TRON,
|
||||
WALLET_SOLANA,
|
||||
WALLET_XRP,
|
||||
WALLET_POLKADOT,
|
||||
WALLET_CARDANO_SHELLEY,
|
||||
WALLET_CARDANO_BYRON,
|
||||
WALLET_DOGE // Dogecoin
|
||||
WALLET_UNKNOWN = 0,
|
||||
WALLET_BTC_P2PKH,
|
||||
WALLET_BTC_P2SH,
|
||||
WALLET_BTC_BECH32,
|
||||
WALLET_ETH_ERC20, // ETH、ERC20(含 USDT-ERC20)
|
||||
WALLET_USDT_OMNI, // USDT Omni,BTC 网络,格式同 BTC
|
||||
WALLET_USDT_TRC20, // USDT TRC20
|
||||
WALLET_TRON,
|
||||
WALLET_SOLANA,
|
||||
WALLET_XRP,
|
||||
WALLET_POLKADOT,
|
||||
WALLET_CARDANO_SHELLEY,
|
||||
WALLET_CARDANO_BYRON,
|
||||
WALLET_DOGE // Dogecoin
|
||||
};
|
||||
|
||||
enum AddressType {
|
||||
ADDR_BTC = 0,
|
||||
ADDR_ERC20,
|
||||
ADDR_OMNI,
|
||||
ADDR_TRC20,
|
||||
ADDR_SOL,
|
||||
ADDR_XRP,
|
||||
ADDR_ADA,
|
||||
ADDR_DOGE,
|
||||
ADDR_DOT,
|
||||
ADDR_TRON,
|
||||
MAX_WALLET_NUM,
|
||||
ADDR_BTC = 0,
|
||||
ADDR_ERC20,
|
||||
ADDR_OMNI,
|
||||
ADDR_TRC20,
|
||||
ADDR_SOL,
|
||||
ADDR_XRP,
|
||||
ADDR_ADA,
|
||||
ADDR_DOGE,
|
||||
ADDR_DOT,
|
||||
ADDR_TRON,
|
||||
MAX_WALLET_NUM,
|
||||
};
|
||||
|
||||
inline WalletType detectWalletType(const std::string& address_raw) {
|
||||
std::string address = address_raw;
|
||||
address.erase(0, address.find_first_not_of(" \t\n\r"));
|
||||
address.erase(address.find_last_not_of(" \t\n\r") + 1);
|
||||
inline WalletType detectWalletType(const std::string& address_raw)
|
||||
{
|
||||
std::string address = address_raw;
|
||||
address.erase(0, address.find_first_not_of(" \t\n\r"));
|
||||
address.erase(address.find_last_not_of(" \t\n\r") + 1);
|
||||
|
||||
// 1. ETH/ERC20(0x 开头)
|
||||
static const std::regex eth_regex("^0x[a-fA-F0-9]{40}$");
|
||||
if (std::regex_match(address, eth_regex)) return WALLET_ETH_ERC20;
|
||||
// 1. ETH/ERC20(0x 开头)
|
||||
static const std::regex eth_regex("^0x[a-fA-F0-9]{40}$");
|
||||
if (std::regex_match(address, eth_regex)) return WALLET_ETH_ERC20;
|
||||
|
||||
// 2. TRC20(T 开头)
|
||||
static const std::regex trc20_regex("^T[1-9A-HJ-NP-Za-km-z]{33}$");
|
||||
if (std::regex_match(address, trc20_regex)) return WALLET_USDT_TRC20;
|
||||
// 2. TRC20(T 开头)
|
||||
static const std::regex trc20_regex("^T[1-9A-HJ-NP-Za-km-z]{33}$");
|
||||
if (std::regex_match(address, trc20_regex)) return WALLET_USDT_TRC20;
|
||||
|
||||
// 3. BTC Bech32(bc1 开头)
|
||||
static const std::regex btc_bech32_regex("^bc1[0-9a-z]{6,}$");
|
||||
if (std::regex_match(address, btc_bech32_regex)) return WALLET_BTC_BECH32;
|
||||
// 3. BTC Bech32(bc1 开头)
|
||||
static const std::regex btc_bech32_regex("^bc1[0-9a-z]{6,}$");
|
||||
if (std::regex_match(address, btc_bech32_regex)) return WALLET_BTC_BECH32;
|
||||
|
||||
// 4. BTC P2PKH(1 开头)
|
||||
static const std::regex btc_p2pkh_regex("^1[1-9A-HJ-NP-Za-km-z]{25,34}$");
|
||||
if (std::regex_match(address, btc_p2pkh_regex)) return WALLET_BTC_P2PKH;
|
||||
// 4. BTC P2PKH(1 开头)
|
||||
static const std::regex btc_p2pkh_regex("^1[1-9A-HJ-NP-Za-km-z]{25,34}$");
|
||||
if (std::regex_match(address, btc_p2pkh_regex)) return WALLET_BTC_P2PKH;
|
||||
|
||||
// 5. BTC P2SH(3 开头)
|
||||
static const std::regex btc_p2sh_regex("^3[1-9A-HJ-NP-Za-km-z]{25,34}$");
|
||||
if (std::regex_match(address, btc_p2sh_regex)) return WALLET_BTC_P2SH;
|
||||
// 5. BTC P2SH(3 开头)
|
||||
static const std::regex btc_p2sh_regex("^3[1-9A-HJ-NP-Za-km-z]{25,34}$");
|
||||
if (std::regex_match(address, btc_p2sh_regex)) return WALLET_BTC_P2SH;
|
||||
|
||||
// 6. XRP(r 开头,Base58)
|
||||
static const std::regex xrp_regex("^r[1-9A-HJ-NP-Za-km-z]{24,34}$");
|
||||
if (std::regex_match(address, xrp_regex)) return WALLET_XRP;
|
||||
// 6. XRP(r 开头,Base58)
|
||||
static const std::regex xrp_regex("^r[1-9A-HJ-NP-Za-km-z]{24,34}$");
|
||||
if (std::regex_match(address, xrp_regex)) return WALLET_XRP;
|
||||
|
||||
// 7. Dogecoin(D 开头,Base58)
|
||||
static const std::regex doge_regex("^D[5-9A-HJ-NP-Ua-km-z]{33}$");
|
||||
if (std::regex_match(address, doge_regex)) return WALLET_DOGE;
|
||||
// 7. Dogecoin(D 开头,Base58)
|
||||
static const std::regex doge_regex("^D[5-9A-HJ-NP-Ua-km-z]{33}$");
|
||||
if (std::regex_match(address, doge_regex)) return WALLET_DOGE;
|
||||
|
||||
// 8. Cardano Shelley(addr1 开头)
|
||||
static const std::regex ada_shelley_regex("^addr1[0-9a-z]{20,}$");
|
||||
if (std::regex_match(address, ada_shelley_regex)) return WALLET_CARDANO_SHELLEY;
|
||||
// 8. Cardano Shelley(addr1 开头)
|
||||
static const std::regex ada_shelley_regex("^addr1[0-9a-z]{20,}$");
|
||||
if (std::regex_match(address, ada_shelley_regex)) return WALLET_CARDANO_SHELLEY;
|
||||
|
||||
// 9. Cardano Byron(DdzFF 开头)
|
||||
if (address.find("DdzFF") == 0) return WALLET_CARDANO_BYRON;
|
||||
// 9. Cardano Byron(DdzFF 开头)
|
||||
if (address.find("DdzFF") == 0) return WALLET_CARDANO_BYRON;
|
||||
|
||||
// 10. Polkadot(长度 47–48,Base58)
|
||||
static const std::regex dot_regex("^[1-9A-HJ-NP-Za-km-z]{47,48}$");
|
||||
if (std::regex_match(address, dot_regex)) return WALLET_POLKADOT;
|
||||
// 10. Polkadot(长度 47–48,Base58)
|
||||
static const std::regex dot_regex("^[1-9A-HJ-NP-Za-km-z]{47,48}$");
|
||||
if (std::regex_match(address, dot_regex)) return WALLET_POLKADOT;
|
||||
|
||||
// 11. Solana(32–44,无前缀,Base58)→ 容易误判,必须放最后
|
||||
static const std::regex solana_regex("^[1-9A-HJ-NP-Za-km-z]{32,44}$");
|
||||
if (std::regex_match(address, solana_regex)) return WALLET_SOLANA;
|
||||
// 11. Solana(32–44,无前缀,Base58)→ 容易误判,必须放最后
|
||||
static const std::regex solana_regex("^[1-9A-HJ-NP-Za-km-z]{32,44}$");
|
||||
if (std::regex_match(address, solana_regex)) return WALLET_SOLANA;
|
||||
|
||||
return WALLET_UNKNOWN;
|
||||
return WALLET_UNKNOWN;
|
||||
}
|
||||
|
||||
inline std::string walletTypeToString(WalletType type) {
|
||||
switch (type) {
|
||||
case WALLET_BTC_P2PKH: return "Bitcoin P2PKH (includes USDT-OMNI)";
|
||||
case WALLET_BTC_P2SH: return "Bitcoin P2SH (includes USDT-OMNI)";
|
||||
case WALLET_BTC_BECH32: return "Bitcoin Bech32";
|
||||
case WALLET_ETH_ERC20: return "Ethereum / ERC20 (includes USDT-ERC20)";
|
||||
case WALLET_USDT_TRC20: return "USDT TRC20";
|
||||
case WALLET_TRON: return "TRON (same as USDT-TRC20)";
|
||||
case WALLET_SOLANA: return "Solana";
|
||||
case WALLET_XRP: return "XRP";
|
||||
case WALLET_POLKADOT: return "Polkadot";
|
||||
case WALLET_CARDANO_SHELLEY: return "Cardano Shelley";
|
||||
case WALLET_CARDANO_BYRON: return "Cardano Byron";
|
||||
case WALLET_DOGE: return "Dogecoin";
|
||||
default: return "Unknown or Unsupported";
|
||||
}
|
||||
inline std::string walletTypeToString(WalletType type)
|
||||
{
|
||||
switch (type) {
|
||||
case WALLET_BTC_P2PKH:
|
||||
return "Bitcoin P2PKH (includes USDT-OMNI)";
|
||||
case WALLET_BTC_P2SH:
|
||||
return "Bitcoin P2SH (includes USDT-OMNI)";
|
||||
case WALLET_BTC_BECH32:
|
||||
return "Bitcoin Bech32";
|
||||
case WALLET_ETH_ERC20:
|
||||
return "Ethereum / ERC20 (includes USDT-ERC20)";
|
||||
case WALLET_USDT_TRC20:
|
||||
return "USDT TRC20";
|
||||
case WALLET_TRON:
|
||||
return "TRON (same as USDT-TRC20)";
|
||||
case WALLET_SOLANA:
|
||||
return "Solana";
|
||||
case WALLET_XRP:
|
||||
return "XRP";
|
||||
case WALLET_POLKADOT:
|
||||
return "Polkadot";
|
||||
case WALLET_CARDANO_SHELLEY:
|
||||
return "Cardano Shelley";
|
||||
case WALLET_CARDANO_BYRON:
|
||||
return "Cardano Byron";
|
||||
case WALLET_DOGE:
|
||||
return "Dogecoin";
|
||||
default:
|
||||
return "Unknown or Unsupported";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ size_t zstd_compress_auto(
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize,
|
||||
size_t threshold
|
||||
) {
|
||||
)
|
||||
{
|
||||
// 检查输入有效性
|
||||
if (!cctx || !dst || !src) {
|
||||
return ZSTD_error_GENERIC;
|
||||
@@ -26,7 +27,7 @@ size_t zstd_compress_auto(
|
||||
while (input.pos < input.size) {
|
||||
ret = ZSTD_compressStream2(cctx, &output, &input, ZSTD_e_continue);
|
||||
if (ZSTD_isError(ret)) break;
|
||||
|
||||
|
||||
// 输出缓冲区已满(理论上不应发生,因 dstCapacity >= ZSTD_compressBound)
|
||||
if (output.pos == output.size) {
|
||||
return ZSTD_error_dstSize_tooSmall;
|
||||
|
||||
Reference in New Issue
Block a user