style: Format source code and support grouping client

This commit is contained in:
yuanyuanxiang
2025-10-15 04:32:59 +08:00
parent 77087d2e06
commit 6b81ad1f81
244 changed files with 43052 additions and 42562 deletions

View File

@@ -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)

View File

@@ -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)

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}
};

View File

@@ -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>
}

View File

@@ -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;
}
}
};

View File

@@ -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.
*/

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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);

View File

@@ -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;
}
};

View File

@@ -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;
}
}
};

View File

@@ -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;
}
};

View File

@@ -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

View File

@@ -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(&currentTime);
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(&currentTime);
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

View File

@@ -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));
}

View File

@@ -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
View 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><38><CEBB><EFBFBD><EFBFBD>
static inline uint8_t rol8(uint8_t val, int shift) {
return (val << shift) | (val >> (8 - shift));
}
// <20><><EFBFBD><EFBFBD><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
}
}
};

View File

@@ -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])

View File

@@ -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 OmniBTC 网络,格式同 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 OmniBTC 网络,格式同 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/ERC200x 开头)
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/ERC200x 开头)
static const std::regex eth_regex("^0x[a-fA-F0-9]{40}$");
if (std::regex_match(address, eth_regex)) return WALLET_ETH_ERC20;
// 2. TRC20T 开头)
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. TRC20T 开头)
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 Bech32bc1 开头)
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 Bech32bc1 开头)
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 P2PKH1 开头)
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 P2PKH1 开头)
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 P2SH3 开头)
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 P2SH3 开头)
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. XRPr 开头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. XRPr 开头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. DogecoinD 开头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. DogecoinD 开头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 Shelleyaddr1 开头)
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 Shelleyaddr1 开头)
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 ByronDdzFF 开头)
if (address.find("DdzFF") == 0) return WALLET_CARDANO_BYRON;
// 9. Cardano ByronDdzFF 开头)
if (address.find("DdzFF") == 0) return WALLET_CARDANO_BYRON;
// 10. Polkadot长度 4748Base58
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长度 4748Base58
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. Solana3244无前缀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. Solana3244无前缀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";
}
}

View File

@@ -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;