base64 编码
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
static const char base64_charset[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int base64_encode(uint8_t in[], uint8_t out[]) { // unsafe
size_t in_len = strlen(reinterpret_cast<char *>(in));
if (in_len == 0)
return 0;
size_t i = 0, j = 0;
while (i < in_len) {
uint8_t c1 = i < in_len ? in[i++] : 0;
uint8_t c2 = i < in_len ? in[i++] : 0;
uint8_t c3 = i < in_len ? in[i++] : 0;
out[j++] = base64_charset[c1 >> 2];
out[j++] = base64_charset[(c1 & 3) << 4 | (c2 >> 4)];
out[j++] =
i < in_len + 2 ? base64_charset[(c2 & 15) << 2 | (c3 >> 6)] : '=';
out[j++] = i < in_len + 1 ? base64_charset[c3 & 63] : '=';
}
return j;
}
int main() {
char test[] = "this is an example";
char res[100] = {};
size_t reslen = base64_encode((uint8_t *)test, (uint8_t *)res);
cout << res << endl << reslen << endl;
}
RC4
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
inline void swap_elements(uint8_t *S, uint8_t a, uint8_t b) {
uint8_t tmp = S[a];
S[a] = S[b];
S[b] = tmp;
}
void rc4_skip(const uint8_t *key, size_t key_len, size_t skip, uint8_t *data,
size_t data_len) {
uint8_t S[256], *pos = data;
size_t kpos = 0;
// Setup RC4 state
for (uint32_t i = 0; i < 256; i++) {
S[i] = i;
}
for (uint32_t i = 0, j = 0; i < 256; i++) {
j = (j + S[i] + key[kpos++]) & 0xff;
if (kpos >= key_len) {
kpos = 0;
}
swap_elements(S, i, j);
}
// Skip the start of the stream
uint32_t i = 0, j = 0;
for (uint32_t k = 0; k < skip; k++) {
i = (i + 1) & 0xff;
j = (j + S[i]) & 0xff;
swap_elements(S, i, j);
}
// Apply RC4 to data
for (uint32_t k = 0; k < data_len; k++) {
i = (i + 1) & 0xff;
j = (j + S[i]) & 0xff;
swap_elements(S, i, j);
*pos++ ^= S[(S[i] + S[j]) & 0xff];
}
}
void rc4(uint8_t *buf, size_t len, const uint8_t *key, size_t key_len) {
rc4_skip(key, key_len, 0, buf, len);
}
int main() {
char test[100] = "this is an example";
char key[100] = "key";
size_t test_len = strlen(test);
rc4((uint8_t *)test, test_len, (uint8_t *)key, strlen(key));
cout << test << endl;
// decrypt
rc4((uint8_t *)test, test_len, (uint8_t *)key, strlen(key));
cout << test << endl;
}
IDA 里反编译效果(clang++ -Ofast)
do
{
v21 = *((_BYTE *)&v50[0].__locale_ + v18);
v19 += v21 + v34[v20];
if ( v20 + 1 < v5 )
++v20;
else
v20 = 0LL; //S盒初始化交换
*((_BYTE *)&v50[0].__locale_ + v18) = *((_BYTE *)&v50[0].__locale_ + v19);
*((_BYTE *)&v50[0].__locale_ + v19) = v21;
++v18;
}
while ( v18 != 256 );
if ( v3 )
{
v22 = 0LL;
v23 = 0;
LOBYTE(v24) = 0;
do
{
v24 = (unsigned __int8)(v24 + 1);
v25 = *((unsigned __int8 *)&v50[0].__locale_ + v24);
v23 += v25;
*((_BYTE *)&v50[0].__locale_ + v24) = *((_BYTE *)&v50[0].__locale_ + (unsigned __int8)v23); // S盒加密交换
*((_BYTE *)&v50[0].__locale_ + (unsigned __int8)v23) = v25;
__s[v22++] ^= *((_BYTE *)&v50[0].__locale_ + (unsigned __int8)(*((_BYTE *)&v50[0].__locale_ + v24) + v25)); // 最后的RPG流异或
}
while ( v3 > (unsigned int)v22 );
}
特征点在前面的交换与最后只有一次的异或流操作