Hey there, someone know how should I convert a string to const char* without losing data in C++? I saw Cryless~ was using a vector<char>, what's the ideal option to do it and how could I do it?
#include <string>
int main() {
std::string exampleString = "I'm a string";
const char* exampleCharArray = exampleString.c_str();
return 0;
}
This is NosTale related because in order to make a Clientless Bot, you need to use a packet (const char*) to send it via socket, and I don't know if I can encrypt directly on the const char* or I need to pass the packet to a string, encrypt it and then pass it to const char*.Quote:
I don't know why this should be Nostale related. But:
If you use std::string, e.g.:
Code:#include <string> int main() { std::string exampleString = "I'm a string"; const char* exampleCharArray = exampleString.c_str(); return 0; }
const char* packet = "NoS0575 7031428 "Username" 3213852420455EE02E4F9FB7E1263751BA49DC01278E8D8AC6B094C2AD555ABE3512267B6A2D9528A2234E6A90E295E95E124AE0AB2E54C406C49B533293B3CF c594947f-d4a9-4462-b545-ad7ddbfd71a2 006EC080\x0B0.9.3.3104 0 2F65F4A00E723E4281EFE51CACE4039D";
std::string packetString = packet;
int packetLength = getLength(packet);
for (int i = 0; i < packetLength; i++)
{
packetString[i] = (packetString[i] ^ 0xC3) + 0xF;
}
// Here is the problem
const char* exampleCharArray = packetString.c_str();
std::cout << exampleCharArray << std::endl; // Only prints 13 chars
Check what the content of the encrypted char array is.Quote:
My question is: why when I try to print the const char* encrypted login packet it just prints some few characters? And only send few characters? Here's code.
Code:const char* packet = "NoS0575 7031428 "Username" 3213852420455EE02E4F9FB7E1263751BA49DC01278E8D8AC6B094C2AD555ABE3512267B6A2D9528A2234E6A90E295E95E124AE0AB2E54C406C49B533293B3CF c594947f-d4a9-4462-b545-ad7ddbfd71a2 006EC080\x0B0.9.3.3104 0 2F65F4A00E723E4281EFE51CACE4039D"; std::string packetString = packet; int packetLength = getLength(packet); for (int i = 0; i < packetLength; i++) { packetString[i] = (packetString[i] ^ 0xC3) + 0xF; } // Here is the problem const char* exampleCharArray = packetString.c_str(); std::cout << exampleCharArray << std::endl; // Only prints 13 chars
int main() {
// input packet
const char* buffer = "NoS0575 7031428 Test 3213852420455EE02E4F9FB7E1263751BA49DC01278E8D8AC6B094C2AD555ABE3512267B6A2D9528A2234E6A90E295E95E12"
"4AE0AB2E54C406C49B533293B3CF c594947f-d4a9-4462-b545-ad7ddbfd71a2 006EC080\x0B0.9.3.3104 0 2F65F4A00E723E4281EFE51CACE4039D";
// Instatiate new vector
std::vector<char> packetVector(buffer, buffer + strlen(buffer));
// Encryption part
for (int i = 0; i < packetVector.size(); ++i) {
packetVector[i] = (packetVector[i] ^ 0xC3) + 0xF;
}
// Console output part (if you really want to print the encrypted string)
for (auto it = packetVector.begin(); it != packetVector.end(); ++it) {
std::cout << std::to_string(*it) << " ";
}
return 0;
}
Couldn't I work with strings instead of vectors? And, is there a possible way to try avoiding the "\0" while you convert string to const char*?Quote:
Check what the content of the encrypted char array is.
I would think that on index 13 there is null byte (\0)
Edit: You should convert the char pointer to a std::vector<char> since you lose data being prefixed by a \0.
Your code could look as follows:
As you can see, I was right. The char on index 13 is a \0.Code:int main() { // input packet const char* buffer = "NoS0575 7031428 Test 3213852420455EE02E4F9FB7E1263751BA49DC01278E8D8AC6B094C2AD555ABE3512267B6A2D9528A2234E6A90E295E95E12" "4AE0AB2E54C406C49B533293B3CF c594947f-d4a9-4462-b545-ad7ddbfd71a2 006EC080\x0B0.9.3.3104 0 2F65F4A00E723E4281EFE51CACE4039D"; // Instatiate new vector std::vector<char> packetVector(buffer, buffer + strlen(buffer)); // Encryption part for (int i = 0; i < packetVector.size(); ++i) { packetVector[i] = (packetVector[i] ^ 0xC3) + 0xF; } // Console output part (if you really want to print the encrypted string) for (auto it = packetVector.begin(); it != packetVector.end(); ++it) { std::cout << std::to_string(*it) << " "; } return 0; }
[Only registered and activated users can see links. Click Here To Register...]
Output:
[Only registered and activated users can see links. Click Here To Register...]
A null byte marks the end of a string in C. Since C is a subset of C++, C++'s std::string uses a char array in the background.
When you e.g. set the value of std::string to "Testabc\0abctest", it removes the abctest because std::string's strlen() counts the number of chars in a string until there is a \0.
No and no.Quote:
Couldn't I work with strings instead of vectors? And, is there a possible way to try avoiding the "\0" while you convert string to const char*?
I figured out how to succesfully send and recv packets with sockets but now I have a "problem". I've copied a login packet using packetlooger and send it via socket and decrypt the answer but it says "failc 1" which means wrong client version, but I checked out if the client version and it was good. I don't know what's wrong.Quote:
std::vector has a data() function which returns a char array.
[Only registered and activated users can see links. Click Here To Register...]
Yes, look.Quote:
Is the packet made with the current client version?
std::string encryptPacket(std::string& packet)
{
for (int i = 0; i < packet.length(); i++)
{
packet[i] = (packet[i] ^ 0xC3) + 0x0F;
}
return packet;
}
// This account is a 10 minutes hotmail account, so I don't care about it
std::string loginPacket = "NoS0575 3041001 dnj92442 BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413 c594947f-d4a9-4462-b545-ad7ddbfd71a2 007B297D\x0B0.9.3.3104 0 E932E27F6E51675C350CD00C4558EA13\xA";
// Maybe the \x0B or the \xA is incorrect or make it crash
int stringLength = loginPacket.length();
send(ConnectSocket, loginPacket.c_str(), stringLength, 0); // This is what I send
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); // This is to get recv
if (iResult > 0)
{
printf("Bytes received: %d\n", iResult);
std::cout << "[RECV]: ";
for (int i = 0; i < iResult; i++)
{
std::cout << (BYTE)(recvbuf[i] - 0xF);
}
}