Remove null byte every X byte c++ WINAPI - c++

I have a buffer type like this:
unsigned char buffer[] = {
0xB8, 0xB8, 0x00, 0xB8, 0xB8, 0x00, 0xB8, 0xB8, 0x00, 0xB8, 0xB8, 0x00,..
};
So I need to remove the null byte every X (every 2 bytes in this example). I don't want to remove all null byte because in my buffer I have melt bytes.
So just need to remove a range and in WinAPI. How can I do that?
I'm still not very comfortable with C++, also the buffer can be big.
I think the right way is by copy the buffer by memcpy in a loop but I can't find the syntax.

It seems that you don't want to use any of the more powerful features of C++ so I suspect that you are really looking for a C style routine. That would look like this:
void copyskip(void *dest, const void *src, size_t srclen, size_t skip)
{
size_t destidx = 0;
for (size_t srcidx=0; srcidx<srclen; )
{
if ((srcidx+1) % skip != 0)
{
((char*)dest)[destidx] = ((char*)src)[srcidx];
destidx++;
}
srcidx++;
}
}
You'd need to allocate the destination buffer before calling. And for your example you would pass 3 for the skip parameter.
Personally I'd much rather do it using C++ standard containers, but this is what I think you asked for.

Related

C++ Pass bytes from char* to a BYTE*

I would like to know how to pass/COPY a sequence of bytes represented as a char* to a BYTE* in C++ in Windows.
Let's say I have this char* :
const char *ByteString = "\x3B\xC8\x74\x1B"
How would I COPY each byte from this char* to a BYTE *Bytes and vice-versa ?
EDIT: Thanks alot for everyone's help !
The definition of BYTE is:
typedef unsigned char BYTE;
which is not the same as a const char, so you'd need to convert it, but note that casting away const from something declared const to start with results in undefined behaviour and trying to actually change the data poses an even bigger risk.
BYTE* Bytes = reinterpret_cast<BYTE*>(const_cast<char*>(ByteString));
Edit: I just noticed that converting a const char* to a BYTE* was taken out of the question but I'll leave it here for now.
Copying the data (not as a zero terminated string) could be done like this:
const char ByteString[] = "\x3B\xC8\x74\x1B";
BYTE* Bytes = new BYTE[sizeof(ByteString)-1];
std::memcpy(Bytes, ByteString, sizeof(ByteString)-1);
// Use your Bytes
delete[] Bytes; // manual delete when you are done
Or better:
const char ByteString[] = "\x3B\xC8\x74\x1B";
std::basic_string<BYTE> Bytes( reinterpret_cast<const BYTE*>(ByteString), sizeof(ByteString)-1 );
// use Bytes
// Bytes.data() returns a BYTE*
// Bytes.size() returns the length.
But given the nature of what you are doing, you could probably skip these conversions and use an array of the correct type to start with:
BYTE Bytes[] = { 0xA1, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xC8, 0x74, 0x1B };
or
std::basic_string<BYTE> Bytes({ 0xA1, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xC8, 0x74, 0x1B });
These won't need any conversions when all you deal with is raw BYTE data. Here's an example using ReadProcessMemory and a basic_string for a buffer and pattern.
using BYTEstr = std::basic_string<BYTE>; // just for convenience
BYTEstr Buffer(1024, 0); // 1024 BYTES initialized with 0
BYTEstr Pattern({ 0xA1, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xC8, 0x74, 0x1B });
ReadProcessMemory(hProcess, lpBaseAddress, Buffer.data(), Buffer.size(), &lpNumberOfBytesRead);
BYTEstr::size_type pos = Buffer.find(Pattern);
if (pos == BYTEstr::npos) {
std::cout << "Pattern not found\n";
} else {
std::cout << "Pattern found at position " << pos << "\n";
}
To respect const, use
const BYTE *Bytes = reinterpret_cast<const BYTE*>(ByteString);
and vice versa:
const char *ByteString = reinterpret_cast<const char *>(Bytes);
If you want to make copy of the buffer so that you can modify it, use
len = LenOfChrStr;
BYTE *Bytes = new BYTE[len];
memcpy(Bytes, ByteStr, len);
Given a char const * array of characters, we can make a new buffer with readwrite BYTEs for the API to possibly edit:
char const *ByteString = "\x3B\xC8\x74\x1B";
auto len = std::strlen(ByteString) + 1;
auto ptr = std::make_unique<BYTE[]>(len);
std::memcpy(ptr.get(), ByteString, len);
If you need to surrender the ownership of the memory to the function:
Func(ptr.release());
But if you want to keep the ownership yourself:
Func(ptr.get());
In MSVC (I guess this is your compiler for WinAPI application) you can make the char type unsigned with /J option (more here: https://learn.microsoft.com/en-us/cpp/build/reference/j-default-char-type-is-unsigned?view=vs-2017). If you do this, BYTE becomes the same as char and no conversion would be necessary.
Please note, this might have some other side effects in your application.

How do I assign existing array values into an array pointer?

I have a program that needs to use a large array (700,000 elements). I tried to assign it as per a normal array:
byte array1[700000] = {0xE8, 0x39, 0xF4, 0xB7, 0x69, ~~699995 other values~~ };
But then, I was met with a segmentation fault. After a bit of research, it was suggested that I put it on the heap. So, I did:
byte* array1 = (byte*) malloc(700000 * sizeof(byte) /* Just to be safe */);
I've used pointers before, and normally I would use a loop to mess around with it. But, in this case, all of the values already exist. How do I put all of those in the new array1? I cannot use external files (i.e. I cannot read from a .txt file).
This does not work (Too many initializer values according to Visual Studio):
byte* array1 = (byte*) malloc(700000 * sizeof(byte));
array1 = { ~~ 700k comma-separated values ~~ };
Sample on how I plan to use it:
#include <stdio.h>
int main(int argc, char* argv[]) {
byte big_array[700000] = {0xE8, 0x39, 0xF4, ~~699995 other values~~ };
some_function(big_array);
return 0;
}
If you are able to use a C++11 compiler, you should use a std::vector.
std::vector<byte> array1 = {0xE8, 0x39, 0xF4, 0xB7, 0x69, ~~9995 other values~~ };

Passing the Number of Elements in an Array to Function?

I am writing a DLL that passes a char array to a function. I define that char array with 22 elements here:
unsigned char data[22] = { 0x00, 0x0A, 0x00, 0x09, 0x70, 0x00, 0x72, 0x00,
0x6F, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, 0x00,
0x79, 0x00 };
Now, I try to pass this array to my function declared as:
bool sendData(unsigned char* sData, unsigned long sSize);
With these arguments:
sendData(data, 22);
This code compiles, but crashes the program when this function is called. Taking a closer look while debugging, I can see that there's an access violation in my function sendData. Looking even further, I see the values of data and sData at run-time:
data points to the 22 byte char array with correct values (obviously)
sData points to a char array that is null-terminated by the first byte, only containing one value (0)
It is clear to me that the compiler does not know to allocate 22 bytes for sData, simply because I do not specify any length for it. So my question is:
How do I specify the length of the sData so that the argument
passed won't terminate early?
If I'm wrong about the issue, please correct me and explain it further. Thanks for any help in advance!
EDIT:
I understand that \0 (the first byte and many more in data) is a null-terminator and will prematurely end the array. What I am asking is how to avoid this. My understanding is that sData is never given a specific length and therefore stops on \0, but I may be wrong.
I was asked to supply my sendData function:
bool sendData(unsigned char* sData, unsigned long sSize)
{
try
{
Send(sData, sSize);
return true;
}
catch (...)
{
return false;
}
}
Send is calling a function from another module, but isn't relevant to the issue, as the error occurs beforehand when the sData argument is passed to sendData.
No allocation of sData is going to happen, it just points to your array. It displays as empty in the debugger because it displays a char* as a string, and strings end when there is a '/0', your first byte. This does not mean sData does not have the correct data. Write sData[0]. sData[1], etc, in your debugger to see the correct values.

C++ array with command line variable

My array looks something like this;
unsigned char send_bytes[] = { 0x0B, 0x11, 0xA6, 0x05, 0x00, 0x00, 0x70 };
One of the values is a variable that can change all the time.. so I tried something like this;
const char* input = "0x05";
unsigned char send_bytes[] = { 0x0B, 0x11, 0xA6, input, 0x00, 0x00, 0x70 };
When I compile I get a warning;
warning: initialization makes integer from pointer without a cast
I am a little confused on the conversion I need to do.. since the array has hex strings in it.. and the input string is a char..
in the first line you are declaring a pointer to const char, and initializing to the beginning of string "0x05", that's fine, but it is not the thing you are trying to do.
in the second line, you try to initialize the fourth array element (an unsigned char) with the value of the pointer you assigned to the input variable in the first line. The compiler says you are pretending to embed a pointer value (the address of "0x05" string) into a char variable, so that's why it complained. And also it is not what you intend.
also, take into account that if you are using binary data (from the fact you are initializing arrays with hex numbers) you had better to use unsigned char for binaries, as signed char is valid only for -128 to +127 values, you can expect some more unpredictable behaviour. Perhaps, a declaration typedef unsigned char byte; can do things easier.
typedef unsigned char byte;
byte send_bytes[] = { 0x0b, 0x11, 0xa6, 0x00, 0x00, 0x00, 0x70 };
byte &input = send_bytes[3]; /* input is an alias of send_bytes[3] */
BR,
Luis
Maybe explaining exactly what const char* input = "0x05"; does will clear things up for you.
First the compiler computes the string data and creates it as a static object:
const char data[5] = { 0x30, 0x78, 0x30, 0x35, 0x0 };
Then your variable is initialized:
const char *input = &data[0];
Note that input is a pointer with a value that depends entirely upon the location the compiler chooses to store the string data at, and has nothing to do with the contents of the string. So if you say char c = input; then c basically gets assigned a random number.
So you should be asking yourself "Where is the value 0x05 that I want to store in the send_bytes array?" In your code it's encoded as text, rather than as a number that your program can use directly. You need to figure out how to convert from a string of symbols following the hexadecimal scheme of representing numbers into C++'s native representation of numbers.
Here are a couple hints. Part of the operation involves associating values with each digit symbol. The symbol '0' is associated with the value zero, '1' with the value one, and so on, according to the usual hexadecimal system. Second, once you can get the associated value of a symbol, then you can use those values in some basic arithmetic operations to figure out the value of the number represented by the whole string of symbols.
For example, if you have the symbols '1' '2' and 'a', in that order from left to right then the arithmetic to compute what number is represented is 1 * 16 * 16 + 2 * 16 + 10.
The error string is pretty much telling you exactly what's wrong.
input is of type const char* (a pointer to a const char), whereas your array send_bytes is of type unsigned char[] (an array of unsigned chars).
First, signed and unsigned values are still different types, though your error message isn't referring to that specifically.
In reality, your input value isn't a string (as there is no true string type in C++), but a pointer to a character. This means that the input string doesn't hold the byte x05, but rather the bytes {x30, x78, x30, x35, x00}.
The compiler is saying Hey, I've no idea what you're trying to do, so I'm just converting the address that string I don't understand (input) to an unsigned char and adding it to the array.
That means if the string "0x05" starts at location 0xAB, your array will ultimately contain { 0x0B, 0x11, 0xA6, 0xAB, 0x00, 0x00, 0x70 }.
You're going to either have to convert from a string to an integer using a radix of 16, or just not use a string at all.
I'd also recommend reading up on pointers.
The array doesn't have "hex strings" in it - if they were, they would be enclosed in quotation marks, like all strings.
The literals are integers written in hexadecimal notation, and equivalent to
unsigned char send_bytes[] = { 11, 17, 166, input, 0, 0, 112 };
Since it's an array of unsigned char you should put an unsigned char there:
unsigned char input = 0x05;
unsigned char send_bytes[] = { 0x0B, 0x11, 0xA6, input, 0x00, 0x00, 0x70 };
You had better to put in your code:
unsigned char send_bytes[] = { 0x0b, 0x11, 0xa6, 0x00, 0x00, 0x00, 0x70 };
unsigned char &input = send_bytes[3]; /* input is an alias of send_bytes[3] */
this way you can do things like:
input = 0x26;
send_packet(send_bytes);

Error when passing arguments and convert it to hexadecimal

How could insert text by argument and automatically transform it to hex?
I tried with:
unsigned char aesKey[32] = argv[1];
but get errors
The output would be like this:
unsigned char aesKey[32] = {
0x53, 0x28, 0x40, 0x6e, 0x2f, 0x64, 0x63, 0x5d, 0x2d, 0x61, 0x77, 0x40, 0x76, 0x71, 0x77, 0x28,
0x74, 0x61, 0x7d, 0x66, 0x61, 0x73, 0x3b, 0x5d, 0x66, 0x6d, 0x3c, 0x3f, 0x7b, 0x66, 0x72, 0x36
};
unsigned char *buf;
aes256_context ctx;
aes256_init(&ctx, aesKey);
for (unsigned long i = 0; i < lSize/16; i++) {
buf = text + (i * 16);
aes256_encrypt_ecb(&ctx, buf);
}
aes256_done(&ctx);
Thanks in advance
In C and C++, when you have code like
char name[]="John Smith";
The compiler knows at compile time what the size of that char array, and all the values will be. So it can allocate it on the stack frame and assign it the value.
When you have code like
char * strptr = foo();
char str[] = strptr;
The compiler doesn't know what the size and value of the string pointed by strptr is. That is why this is not allowed in C/C++.
In other words, only string literals can be assigned to char arrays, and that too only at the time of declaration.
So
char name[] = "John Smith";
is allowed.
char name[32];
name = "John Smith";
is not allowed.
Use memcpy
So you could use memcpy. (Or use c++ alternative that others have alluded to)
unsigned char *aesKey;
size_t len = (strlen(argv[1])+1)*sizeof(unsigned char);
aesKey = malloc(len);
memcpy(aesKey, argv[1], len);
The old solution
(here is my previous answer, the answer above is better)
So you need to use strncpy.
unsigned char aesKey[32];
strncpy((char *) aesKey, argv[1], 32);
Notice the routine is strncpy not strcpy. strcpy is unsafe. (Thanks PRouleau for the arg fix)
If strncpy is not available in Visual Studio then you may have to try strcpy_s (Thanks Google: user:427390)
In C/C++, the compiler does not automatically manipulate the arrays. You have to specify how to copy them.
The good old way is with memcpy(). A more modern way is with std::copy(). In any case, you have to validate the length of argv[1] before copying into aesKey.
For the conversion into hex, you probably have to transform a string like "AAEE3311" (up to 2*32 chars) into bytes. You should use std::istringstream and fill your aesKey position by position.
Ex:
std::istringstream Input(argv[1]);
Input >> std::hex >> aesKey[0];
I would imagine a program being called as below -
myprog 0x53 0x28 0x40 0x6e 0x2f 0x64 0x63
Inside the program I would have a loop to assign the arguments to the array -
const int size = 32;
unsigned char aesKey[size];
char* p;
for (int i = 1; i < argc || i < size; ++i)
{
aesKey[i] = (unsigned char)strtol(argv[i], &p, 16);
}