I want to read the memory from a process for 16 MB (FFFFFF) and store it in a array, in a way that when I search inside the array like: array[i], i will be the real memory address.
Lets say I want to search from 000000 to FFFFFF, I want to make that jump sizeof(value), get the address from that address and store it in a var.
then if(var==value) return address.
i have this:
ReadProcessMemory(phandle,(void*)address,buffer,0xFFFFFF,0);
EDIT:
i have this (by BlueWanderer answer):
class offset_buffer{
private:
char *buf;
int offset;
public:
offset_buffer(char *in_buf, int in_offset)
: buf(in_buf), offset(in_offset){
}
char & operator[](int in_index){
return buf[in_index - offset];
}
void setOffset(int off){
offset=off;
}
void ReadMemory(){
LPBYTE point;
DWORD primeiroAddress = 0x000000;
DWORD finalAddress = 0xFFFFFF;
//LPBYTE buffer = new BYTE[finalAddress-primeiroAddress];
HANDLE phandle = OpenProcess(PROCESS_VM_READ,0,TargetPID);
ReadProcessMemory(phandle,(void*)primeiroAddress, buf, sizeof(buf), 0);
CloseHandle(phandle);
}
};
main(){
char *buffer = new char[0xFFFFFFF-0x0000000];
int address = 0x0000000;
offset_buffer b(buffer,address);
std::ostringstream ss;
int i=0;
TListItem *ListIt;
b.ReadMemory();
for(address=0x0000000;address<0xFFFFFFF;address+=sizeof(int)){
if(b[address]==StrToInt(Edit1->Text.c_str())){
ss << std::hex << address;
showValue();
ss.str(std::string());
}
}
what is wrong?? can someone help me? why it doesn't work
You want something like this?
class offset_buffer
{
private:
char *buf;
int offset;
public:
offset_buffer(char *in_buf, int in_offset)
: buf(in_buf), offset(in_offset)
{
}
char & operator[](int in_index)
{
return buf[in_index - offset];
}
};
It will map your real address to the index in the array
offset_buffer b(buffer, address);
if (b[0x0C2F8E3] == 123) return 0x0C2F8E3;
Related
int computeHMACSHA1Hash(const char * unhashedcstr, char * hashedcstr, const char * key, int returncode)
{
string hashed;
size_t unhashlength = strlen(unhashedcstr);
char * nonconstunhashcstr = new char[unhashlength];
strcpy_s(nonconstunhashcstr, unhashlength + 1, unhashedcstr);
unsigned char* pixels = reinterpret_cast<unsigned char*>(nonconstunhashcstr);
returncode = 0;
HMAC_CTX* context = HMAC_CTX_new();
size_t unhashedstrlength = sizeof(unhashedcstr);
if (context != NULL)
{
if (HMAC_Init_ex(context, key, strlen(key), EVP_sha1(), NULL))
{
if (HMAC_Update(context, pixels, unhashedstrlength))
{
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int lengthOfHash = 0;
if (HMAC_Final(context, hash, &lengthOfHash))
{
std::stringstream ss;
for (unsigned int i = 0; i < lengthOfHash; ++i)
{
ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
}
hashed = ss.str();
size_t outputSize = hashed.length() + 1; // +1 for null terminator
strcpy_s(hashedcstr, outputSize, hashed.c_str());
returncode = 0;
}
else
{
returncode = 7;
}
}
else
{
returncode = 6;
}
}
else
{
returncode = 5;
}
HMAC_CTX_free(context);
}
else
{
returncode = 4;
}
return returncode;
}
int main()
{
const char * unhashedcstr = "a=services&l=v1&p=open&k=SD58292829&i=20200918125249803&n=2124&t=1600404769&f={\"invoiceCode\": \"11111\",\"invoiceNo\": \"2222\",\"inTaxAmount\": \"\",\"exTaxAmount\": \"\"}";
char * hashedcstr = new char[100];
int returncode = 0;
const char * key = "SD886A11B0EE428F";
int result = computeHMACSHA1Hash(unhashedcstr, hashedcstr, key, returncode);
return 0;
}
I tried the code above to calculating the HMAC SHA1 hash value for a content, but compared the results on https://www.freeformatter.com/hmac-generator.html#before-output
it looks like I didn't do it right. I'm not sure what I have done wrong though. Any help would be appreciated.
It turned out the result was "d916b4c2d277319bbf18076c158f0cbcf6c3bc57", while on the website https://www.freeformatter.com/hmac-generator.html#before-output, the result was "71482b292f2b2a47b3eca6dad5e7350566d60963". Even when I tried using the string "a=services&l=v1&p=open&k=SD58292829&i=20200918125249803&n=2124&t=1600404769&f={"invoiceCode": "11111","invoiceNo": "2222","inTaxAmount": "","exTaxAmount": ""}" which removed the escape characters, the result was "09be98b6129c149e685ed57a1d19651a602cda0d". It didn't match the correct one.
Is there anything wrong with my code?
Your hash is calculated over the bytes a=se, which are the first four bytes of the whole input string. Thus, you get d916b4c2d277319bbf18076c158f0cbcf6c3bc57 instead of the 09be98b6129c149e685ed57a1d19651a602cda0d that would correspond to the whole string.
The reason is this:
size_t unhashedstrlength = sizeof(unhashedcstr);
Here, sizeof(unhashedcstr) is the size of the unhashedcstr pointer itself (which is of type const char*), not the size of the null-terminated C-style string this unhashedcstr pointer is pointing to. You are compiling a 32-bit program, so the size of a pointer is 4 bytes. Thus, unhashedstrlength is 4.
To get the length of the C-style string, you can do this instead:
size_t unhashedstrlength = strlen(unhashedcstr);
But just as a comment, in modern C++, you should avoid using raw pointers (such as const char*, char*, unsigned char*), C functions (like strlen(), strcpy_s()) and manual memory management (new / delete and new[] / delete[]). You should prefer to use std::string and/or std::vector<unsigned char> instead, wherever possible. When you need to pass a buffer's address to an API function, you can use std::string::data(), std::vector::data(), or more generally, std::data().
By the way, you currently leak memory: you dynamically allocate buffers using new[], but you never deallocate those (using delete[]). So that memory is released by the OS only after the program exits. This is called a memory leak.
I have two structure
struct TbtStreamHeader
{
short MsgLen;
short StreamId;
int SeqNo;
TbtStreamHeader()
{
MsgLen = StreamId = 0;
SeqNo = 0;
}
};
struct Multicast_OrderMsg
{
char MsgType; ///'N', 'X', 'M'
long long Timestamp;
double OrderId;
int Token;
char OrderType;
int Price;
int Quantity;
string ToString()
{
std::stringstream ss;
ss<<MsgType<<'|'<<Timestamp<<'|'<<(long long)OrderId<<"|0|"<<Token<<'|'<<OrderType<<'|'<<Price<<'|'<<Quantity;
return ss.str();
}
};
I am reading a file using ifstream, filling that file into the structure object because file is not into the format of structure, then copy the structure into char buffer. Here is the code for better understanding.
TbtStreamHeader hdr;
Multicast_OrderMsg oMsg;
hdr.MsgLen = 38;
hdr.StreamId = streamID;
hdr.SeqNo = 0;
bool firstLine = true;
while(ifs1)
{
if (!getline(ifs1, str1)) break;
istringstream ss(str1);
v1.clear();
while(ss)
{
string s1;
if(!getline( ss, s1, '|' ))
{
break;
}
v1.push_back(s1);
}
if(firstLine)
{
firstLine = false;
seq = atoi(v1[1].c_str());
hdr.SeqNo = seq;
getline(ifs1, str1);
}
else
{
char tempData[38];
int tempBufOffset=0;
hdr.SeqNo++;
oMsg.OrderId = atoll(v1[0].c_str());
oMsg.Token = atoi(v1[1].c_str());
oMsg.OrderType = v1[2][0];
oMsg.Price = atoi(v1[3].c_str());
oMsg.Quantity = atoi(v1[4].c_str());
oMsg.MsgType = 'N';
memcpy(tempData, &hdr, 8);
tempBufOffset += 8;
memcpy(tempData+tempBufOffset, oMsg, 30);
Multicast_OrderMsg* oMsgT = (Multicast_OrderMsg*)tempData+8; //Not able to caste
cout<<oMsgT->ToString()<<endl;
tempBufOffset += 30;
mcastTbt.streams[0].RecoveryPacket(tempData);
}
}
Here cout<< showing me segmentation fault. I am not able to understanding what wrong it is..?
At the location tempData+8 are no Multicast_OrderMsg objects, dereferencing such pointer is undefined behaviour as it violates the strict aliasing rule.
But that on itself does not usually cause seg. faults, the reason is tempData is not big enough to store the aliased Multicast_OrderMsg object. On most implementation the types require to be aligned at least to their size, which causes padding:
struct Multicast_OrderMsg
{
char MsgType; // 1
// Padding 7
long long Timestamp;// 8
double OrderId;// 8
int Token;// 4
char OrderType;// 1
// Padding 3
int Price;// 4
int Quantity;// 4
};
Making the structure 40 bytes long, you only have space for 30. So the printing tries to access memory locations not belonging to you, hence the segfault.
I'm learning about signature scanning and having some problems. My code is sort of ugly but it should work,,, can't understand how to fix my problem. My main function memory.findSignature() in my main returns a garbage value and therefor my when i read and give RemoteHealth a value it is also garbage.
Main:
LPCSTR signature = "\x48\x4A\x85\x2A\x44\x49";
LPCSTR mask = "xxxxxx";
uintptr_t healthAddr = memory.findSignature(CS.client.dwBase, CS.client.dwSize, signature, mask);
int RemoteHealth = memory.readAddress<int>(healthAddr);
std::cout << "value:" << std::hex << RemoteHealth << " address:" << healthAddr <<std::endl;
memory.h:
bool memoryCompare(const byte* data, const byte* mask, const char* szMask) {
for (; *szMask; ++szMask, ++data, ++mask) {
if (*szMask == 'x' && *data != *mask) {
return false;
}
}
return true;
}
uintptr_t findSignature(uintptr_t sigStart, uintptr_t sigSize, const char* signature, const char* mask) {
byte* data = new byte[sigSize];
SIZE_T bytesRead;
ReadProcessMemory(procHandle, (LPVOID)sigStart, data, sigSize, &bytesRead);
for (uintptr_t i = 0; i < sigSize; i++) {
if (this->memoryCompare((const byte*)(data + i), (const byte*)signature, mask)) {
delete[] data;
return sigStart + i;
}
}
delete[] data;
return NULL;
}
I don't know what would explain this but i know the issue is in one of my two memory functions...
http://prntscr.com/mqpx9h
http://prntscr.com/mqpz85
http://prntscr.com/mqpzqm
the return in memoryCompare are flipped, but the values still are garbage in read.... the address just reads as first in module :/
I have a vector defined as:
std::vector<message *>
where message is:
struct message{
static unsigned int last_id;
unsigned int id;
std::string msg;
std::string timestamp;
}
My objective is to send this information using Winsock (from server to client), but this only allows sending chars as it appears in WinSock2.h. Taking this into account, I want to serialize all the information (id, msg and timestamp) in an array of chars in order to send it all together, and in the client, have a function to deserialize so as to have the same vector I had in the server.
How could I implement it?
Any help is appreciated.
The following offers a simple approach for the serialization problem.
However, note that it is not portable. It assumes same environment conditions on both sides (client/server), i.e. endianness and sizeof int and size_t. This assumption is probably unsatisfactory when writing server/client programs, and your code should handle this aspect as well.
For example, if you can say that 32 bits is a sufficient size for the id value and the length of your strings, you can use htonl when serializing, and ntohl when deserializing.
Serializer:
class MessageSerializer
{
public:
MessageSerializer(const message& messageStruct)
: m_msgRef(messageStruct)
, m_msgLength(m_msgRef.msg.length())
, m_timeLength(m_msgRef.timestamp.length())
{}
size_t RequiredBufferSize() const
{
return sizeof(int) + sizeof(size_t)*2 + m_msgLength + m_timeLength;
}
void Serialize(void* buffer) const
{
PushNum (buffer, m_msgRef.id);
PushString (buffer, m_msgRef.msg.c_str(), m_msgLength);
PushString (buffer, m_msgRef.timestamp.c_str(), m_timeLength);
}
private:
const message& m_msgRef;
const size_t m_msgLength;
const size_t m_timeLength;
template<typename INTEGER>
void PushNum(void*& buffer, INTEGER num) const
{
INTEGER* ptr = static_cast<INTEGER*>(buffer);
//copying content
*ptr = num;
//updating the buffer pointer to point the next position to copy
buffer = ++ptr;
}
void PushString(void*& buffer, const char* cstr, size_t length) const
{
PushNum(buffer, length);
//copying string content
memcpy(buffer, cstr, length);
//updating the buffer pointer to point the next position to copy
char* ptr = static_cast<char*>(buffer);
ptr += length;
buffer = ptr;
}
};
Deserializer:
class MessageDeserializer
{
public:
MessageDeserializer(const char* messageBuffer)
: m_msgBuffer(messageBuffer)
{}
void Deserialize(message& messageOut)
{
messageOut.id = PopNum<int>(m_msgBuffer);
messageOut.msg = PopString(m_msgBuffer);
messageOut.timestamp = PopString(m_msgBuffer);
}
private:
const void* m_msgBuffer;
template<typename INTEGER>
INTEGER PopNum(const void*& buffer) const
{
const INTEGER* ptr = static_cast<const INTEGER*>(buffer);
//copying content
INTEGER retVal = *ptr;
//updating the buffer pointer to point the next position to copy
buffer = ++ptr;
return retVal;
}
std::string PopString(const void*& buffer) const
{
size_t length = PopNum<size_t>(buffer);
const char* ptr = static_cast<const char*>(buffer);
//copying content
std::string retVal(ptr, length);
//updating the buffer pointer to point the next position to copy
ptr += length;
buffer = ptr;
return retVal;
}
};
Then your using code could be something like:
//...
MessageSerializer serializer(*myVector[i]);
char* buffer = new char[serializer.RequiredBufferSize()];
serializer.Serialize(buffer);
and:
//...
message myMsg;
MessageDeserializer(input).Deserialize(myMsg);
You can use the Boost serialization library to save/load your structure to an array of char. The boost library is widely used in C++, and if you're not familiar with it, I'd recommend taking a look at it.
Instead of using winsock, you could learn to use Boost sockets and make your C++ code work on almost any platform, instead of just Windows, but that's another topic.
Here's an example of how to serialize your vector, and recover it from the other side of the socket:
#include <vector>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
struct message {
static unsigned int last_id;
unsigned int id;
std::string msg;
std::string timestamp;
template <class ArchiveT>
void serialize(ArchiveT& ar, const unsigned int /*version*/) // function used to serialize (save/load) data from the boost serialization library
{
ar & boost::serialization::make_nvp("LastId", last_id);
ar & boost::serialization::make_nvp("Id", id);
ar & boost::serialization::make_nvp("Msg", msg);
ar & boost::serialization::make_nvp("Timestamp", timestamp);
}
};
unsigned int message::last_id;
template <class T>
void serialize_save(const T& obj, std::string& outString)
{
std::stringstream binaryOut;
boost::archive::binary_oarchive outArchive(binaryOut);
outArchive << obj;
outString = binaryOut.str();
}
template <class T>
void serialize_load(T& dataOut, const void* data, const size_t dataSize)
{
const char* dataPtr = reinterpret_cast<const char*>(data);
std::string dataString(dataPtr, dataPtr + dataSize);
std::stringstream dataStream(dataString);
boost::archive::binary_iarchive binArchive(dataStream);
binArchive >> dataOut;
}
void init_vector(std::vector<message*>& vect) {
const size_t vectorSize = 2;
vect.resize(vectorSize);
for (size_t i = 0; i < vectorSize; i++) {
vect[i] = new message();
vect[i]->last_id = 0;
vect[i]->id = 1;
vect[i]->msg = "This is a message";
vect[i]->timestamp = "12:02pm";
}
}
int main() {
std::vector<message*> messages;
init_vector(messages); // initialize the vector. set it to any data
std::string outputBuffer;
serialize_save(messages, outputBuffer); // save the vector to a string (array of char)
socket_write(outputBuffer.c_str(), outputBuffer.size()); // write the serialized data to the socket
// on the reception side
std::string receiveBuffer;
socket_read(receiveBuffer); // receive socket data
std::vector<message*> receivedMessages;
serialize_load(receivedMessages, receiveBuffer.c_str(), receiveBuffer.size()); // from the array of character recover the vector
// here the vector receivedMessages contains the same values saved in init_vector()
}
You can change the export format if you'd like by changing the boost::archive::binary_iarchive object. For instance, replace it to boost::archive::xml_iarchive for serializing objects to XML. There are other formats provided by the library. Another advantage is that it supports versioning.
Suppose i have a struct whose member values i want to send over the network to another system using winsock 2. I'm using C++ language.
How do i convert it to char * keeping in mind that the struct has to be serialized before sending and also how do i deserialize the char * into struct at the other end? I found boost serialization as a suggestion to similar question but can anyone illustrate with a small code snippet for both serialization and deserialization ?
This question might seem very basic but the other answers to the related posts did not help much.
Following example shows a simplest way to serialize struct into char array and de-serialize it.
#include <iostream>
#include <cstring>
#define BUFSIZE 512
#define PACKETSIZE sizeof(MSG)
using namespace std;
typedef struct MSG
{
int type;
int priority;
int sender;
char message[BUFSIZE];
}MSG;
void serialize(MSG* msgPacket, char *data);
void deserialize(char *data, MSG* msgPacket);
void printMsg(MSG* msgPacket);
int main()
{
MSG* newMsg = new MSG;
newMsg->type = 1;
newMsg->priority = 9;
newMsg->sender = 2;
strcpy(newMsg->message, "hello from server\0");
printMsg(newMsg);
char data[PACKETSIZE];
serialize(newMsg, data);
MSG* temp = new MSG;
deserialize(data, temp);
printMsg(temp);
return 0;
}
void serialize(MSG* msgPacket, char *data)
{
int *q = (int*)data;
*q = msgPacket->type; q++;
*q = msgPacket->priority; q++;
*q = msgPacket->sender; q++;
char *p = (char*)q;
int i = 0;
while (i < BUFSIZE)
{
*p = msgPacket->message[i];
p++;
i++;
}
}
void deserialize(char *data, MSG* msgPacket)
{
int *q = (int*)data;
msgPacket->type = *q; q++;
msgPacket->priority = *q; q++;
msgPacket->sender = *q; q++;
char *p = (char*)q;
int i = 0;
while (i < BUFSIZE)
{
msgPacket->message[i] = *p;
p++;
i++;
}
}
void printMsg(MSG* msgPacket)
{
cout << msgPacket->type << endl;
cout << msgPacket->priority << endl;
cout << msgPacket->sender << endl;
cout << msgPacket->message << endl;
}
You can also have a look at Protocol Buffers from Google which is a platform/language independent library for sending data between hosts.
However, the paradigm is shifted towards writing the protocol first and then fitting your data structures into it. The advantage of this though is that it forces your software architecture to fit well with simple data types.
You can just do
struct MyStruct {
int data;
char* someNullTerminatedName; // Assuming not larger than 1023 chars
std::ostream& serialize(std::ostream& os) const {
char null = '\0';
os.write((char*)&data, sizeof(data));
os.write(someNullTerminatedName, strlen(someNullTerminatedName));
os.write(&null, 1);
return os;
}
std::istream& deserialize(std::istream& is) {
char buffer[1024];
int i = 0;
is.read((char*)&data, sizeof(data));
do { buffer[i] = is.get(); ++i; } while(buffer[i] != '\0');
if (someNullTerminatedName != NULL) free(someNullTerminatedName);
someNullTerminatedName = (char*)malloc(i);
for (i = 0; buffer[i] != '\0'; ++i) {
someNullTerminatedName[i] = buffer[i];
}
return is;
}
};
It's up to you to take care of endianness and differences in size of ints and whatnot.
Example:
MyStruct foo, bar;
std::stringstream stream;
foo.serialize(stream);
// ... Now stream.str().c_str() contains a char* buffer representation of foo.
// For example it might contain [ 1f 3a 4d 10 h e l l o w o r l d \0 ]
bar.deserialize(stream);
// ... Now bar is a copy, via a serial stream of data, of foo.
If you have a socket library that exposes its interface via C++ iostreams then you don't even need the stringstream.
If your struct is POD you can use memcpy:
::memcpy(data, &your_struct, sizeof(YourStruct)));
and vice versa at reception:
::memcpy(&your_struct, data, sizeof(YourStruct)));
Where data is a char*. Don't forget you have to Allocate it, making sure it's big enought and delete it at the end.
Ok I will take the example from the boost web site as I don't understand what you can not understand from it.
I added some comments and changes to it how you can transfer via network. The network code itself is not in here. For this you can take a look at boost::asio.
int main() {
// create and open a character archive for output
// we simply use std::strinstream here
std::stringstream ofs;
// create class instance
const gps_position g(35, 59, 24.567f);
// save data to archive
{
boost::archive::text_oarchive oa(ofs);
// write class instance to archive
oa << g;
// archive and stream closed when destructors are called
}
// now we have const char* ofs.str().c_str()
// transfer those bytes via network
// read them on the other machine
gps_position newg;
{
// create and open an archive for input
std::stringstream ifs(the_string_we_read_from_the_network);
boost::archive::text_iarchive ia(ifs);
// read class state from archive
ia >> newg;
// archive and stream closed when destructors are called
}
return 0;
}