cat_chat_crypto 1

This commit is contained in:
nullifiedcat 2017-07-01 18:24:48 +03:00
parent 4b61c8ac1a
commit ad6c1c3f05
3 changed files with 335 additions and 4 deletions

256
src/base64.h Normal file
View File

@ -0,0 +1,256 @@
#ifndef BASE64_H
#define BASE64_H
#include <string>
const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
class Base64 {
public:
static bool Encode(const std::string &in, std::string *out) {
int i = 0, j = 0;
size_t enc_len = 0;
unsigned char a3[3];
unsigned char a4[4];
out->resize(EncodedLength(in));
int input_len = in.size();
std::string::const_iterator input = in.begin();
while (input_len--) {
a3[i++] = *(input++);
if (i == 3) {
a3_to_a4(a4, a3);
for (i = 0; i < 4; i++) {
(*out)[enc_len++] = kBase64Alphabet[a4[i]];
}
i = 0;
}
}
if (i) {
for (j = i; j < 3; j++) {
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for (j = 0; j < i + 1; j++) {
(*out)[enc_len++] = kBase64Alphabet[a4[j]];
}
while ((i++ < 3)) {
(*out)[enc_len++] = '=';
}
}
return (enc_len == out->size());
}
static bool Encode(const char *input, size_t input_length, char *out, size_t out_length) {
int i = 0, j = 0;
char *out_begin = out;
unsigned char a3[3];
unsigned char a4[4];
size_t encoded_length = EncodedLength(input_length);
if (out_length < encoded_length) return false;
while (input_length--) {
a3[i++] = *input++;
if (i == 3) {
a3_to_a4(a4, a3);
for (i = 0; i < 4; i++) {
*out++ = kBase64Alphabet[a4[i]];
}
i = 0;
}
}
if (i) {
for (j = i; j < 3; j++) {
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for (j = 0; j < i + 1; j++) {
*out++ = kBase64Alphabet[a4[j]];
}
while ((i++ < 3)) {
*out++ = '=';
}
}
return (out == (out_begin + encoded_length));
}
static bool Decode(const std::string &in, std::string *out) {
int i = 0, j = 0;
size_t dec_len = 0;
unsigned char a3[3];
unsigned char a4[4];
int input_len = in.size();
std::string::const_iterator input = in.begin();
out->resize(DecodedLength(in));
while (input_len--) {
if (*input == '=') {
break;
}
a4[i++] = *(input++);
if (i == 4) {
for (i = 0; i <4; i++) {
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3,a4);
for (i = 0; i < 3; i++) {
(*out)[dec_len++] = a3[i];
}
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++) {
a4[j] = '\0';
}
for (j = 0; j < 4; j++) {
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3,a4);
for (j = 0; j < i - 1; j++) {
(*out)[dec_len++] = a3[j];
}
}
return (dec_len == out->size());
}
static bool Decode(const char *input, size_t input_length, char *out, size_t out_length) {
int i = 0, j = 0;
char *out_begin = out;
unsigned char a3[3];
unsigned char a4[4];
size_t decoded_length = DecodedLength(input, input_length);
if (out_length < decoded_length) return false;
while (input_length--) {
if (*input == '=') {
break;
}
a4[i++] = *(input++);
if (i == 4) {
for (i = 0; i <4; i++) {
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3,a4);
for (i = 0; i < 3; i++) {
*out++ = a3[i];
}
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++) {
a4[j] = '\0';
}
for (j = 0; j < 4; j++) {
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3,a4);
for (j = 0; j < i - 1; j++) {
*out++ = a3[j];
}
}
return (out == (out_begin + decoded_length));
}
static int DecodedLength(const char *in, size_t in_length) {
int numEq = 0;
const char *in_end = in + in_length;
while (*--in_end == '=') ++numEq;
return ((6 * in_length) / 8) - numEq;
}
static int DecodedLength(const std::string &in) {
int numEq = 0;
int n = in.size();
for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) {
++numEq;
}
return ((6 * n) / 8) - numEq;
}
inline static int EncodedLength(size_t length) {
return (length + 2 - ((length + 2) % 3)) / 3 * 4;
}
inline static int EncodedLength(const std::string &in) {
return EncodedLength(in.length());
}
inline static void StripPadding(std::string *in) {
while (!in->empty() && *(in->rbegin()) == '=') in->resize(in->size() - 1);
}
private:
static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}
static inline unsigned char b64_lookup(unsigned char c) {
if(c >='A' && c <='Z') return c - 'A';
if(c >='a' && c <='z') return c - 71;
if(c >='0' && c <='9') return c + 4;
if(c == '+') return 62;
if(c == '/') return 63;
return 255;
}
};
#endif // BASE64_H

View File

@ -8,6 +8,7 @@
#include "../common.h"
#include "../netmessage.h"
#include "../hack.h"
#include "../xb64.hpp"
#include "hookedmethods.h"
static CatVar no_invisibility(CV_SWITCH, "no_invis", "0", "Remove Invisibility", "Useful with chams!");
@ -127,6 +128,7 @@ static CatVar newlines_msg(CV_INT, "chat_newlines", "0", "Prefix newlines", "Add
//static CatVar queue_messages(CV_SWITCH, "chat_queue", "0", "Queue messages", "Use this if you want to use spam/killsay and still be able to chat normally (without having your msgs eaten by valve cooldown)");
static CatVar airstuck(CV_KEY, "airstuck", "0", "Airstuck");
static CatVar crypt_chat(CV_SWITCH, "chat_crypto", "0", "Crypto chat", "Start message with !! and it will be only visible to cathook users");
bool SendNetMsg_hook(void* _this, INetMessage& msg, bool bForceReliable = false, bool bVoice = false) {
static size_t say_idx, say_team_idx;
@ -138,13 +140,23 @@ bool SendNetMsg_hook(void* _this, INetMessage& msg, bool bForceReliable = false,
const SendNetMsg_t original = (SendNetMsg_t)hooks::netchannel.GetMethod(offsets::SendNetMsg());
SEGV_BEGIN;
// net_StringCmd
if (msg.GetType() == 4 && (newlines_msg)) {
if (msg.GetType() == 4 && (newlines_msg || crypt_chat)) {
std::string str(msg.ToString());
say_idx = str.find("net_StringCmd: \"say \"");
say_team_idx = str.find("net_StringCmd: \"say_team \"");
if (!say_idx || !say_team_idx) {
offset = say_idx ? 26 : 21;
if (newlines_msg) {
bool crpt = false;
if (crypt_chat) {
std::string msg(str.substr(offset));
msg = msg.substr(0, msg.length() - 2);
if (msg.find("!!") == 0) {
msg = "!!" + xb64::encrypt(msg.substr(2));
str = str.substr(0, offset) + msg + "\"\"";
crpt = true;
}
}
if (!crpt && newlines_msg) {
// TODO move out? update in a value change callback?
newlines = std::string((int)newlines_msg, '\n');
str.insert(offset, newlines);
@ -315,7 +327,7 @@ bool DispatchUserMessage_hook(void* _this, int type, bf_read& buf) {
static const DispatchUserMessage_t original = (DispatchUserMessage_t)hooks::client.GetMethod(offsets::DispatchUserMessage());
SEGV_BEGIN;
if (clean_chat) {
if (clean_chat || crypt_chat) {
if (type == 4) {
loop_index = 0;
s = buf.GetNumBytesLeft();
@ -324,10 +336,22 @@ bool DispatchUserMessage_hook(void* _this, int type, bf_read& buf) {
for (i = 0; i < s; i++)
data[i] = buf.ReadByte();
j = 0;
std::string name;
std::string message;
for (i = 0; i < 3; i++) {
while ((c = data[j++]) && (loop_index < 128)) {
loop_index++;
if ((c == '\n' || c == '\r') && (i == 1 || i == 2)) data[j - 1] = '*';
if (clean_chat)
if ((c == '\n' || c == '\r') && (i == 1 || i == 2)) data[j - 1] = '*';
if (i == 1) name.push_back(c);
if (i == 2) message.push_back(c);
}
}
if (crypt_chat) {
if (message.find("!!") == 0) {
if (xb64::validate(message.substr(2))) {
PrintChat("\x07%06X%s\x01: %s", 0xe05938, name.c_str(), xb64::decrypt(message.substr(2)).c_str());
}
}
}
buf = bf_read(data, s);

51
src/xb64.hpp Normal file
View File

@ -0,0 +1,51 @@
/*
* xb64.hpp
*
* Created on: Jul 1, 2017
* Author: nullifiedcat
*/
#pragma once
#include <string>
#include "base64.h"
namespace xb64 {
std::string crappy_checksum(const std::string& in) {
int s = 0, ss = 0;
for (int i = 0; i < in.length(); i += 2) {
s += (int)in[i];
if (i < in.length() - 1)
ss += (int)in[i + 1] * (int)in[i + 1];
}
return { kBase64Alphabet[s % 64], kBase64Alphabet[ss % 64] };
}
std::string crappy_xorstring(const std::string& in) {
std::string out;
for (int i = 0; i < in.length(); i++) {
// 696969th prime, 13371337th prime
out.push_back(in[i] ^ ((10522103 * in.length()) + i * 244053389 % 256));
}
return out;
}
bool validate(const std::string& in) {
if (in.length() < 2) return false;
return crappy_checksum(in.substr(0, in.length() - 2)) == in.substr(in.length() - 2);
}
std::string decrypt(const std::string& in) {
std::string b64;
Base64::Decode(in.substr(0, in.length() - 2), &b64);
return crappy_xorstring(b64);
}
std::string encrypt(const std::string& in) {
std::string b64;
Base64::Encode(crappy_xorstring(in), &b64);
return b64 + crappy_checksum(b64);
}
}