Shellcode from vector into virtualalloc does not work
I am having a hard time figuring out why the payload isn't working after decryption in example2.cpp
, when executing the compiled exe with the command 'example2.exe > out.txt' I get the shellcode which is valid and does not cause any problem in example.cpp
because I can see the output which is hello world
(at least in my case)
example.cpp
unsigned char out[] = "\x00\x00...";
int main()
{
void *exec = VirtualAlloc(0, sizeof(out), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, out, sizeof(out));
((void(*)())exec)();
}
example2.cpp
void decrypt_run(){
std::vector<unsigned char> decrypted(encrypted.size());
// the encrypted cipher get decrypted and the vector decrypted is filled with unsigned chars
unsigned char buf[decrypted.size()];
// converting the vector to an unsigned char buffer to be passed to memcopy
std::copy(decrypted.begin(), decrypted.end(), buf);
size_t shellcodesize = sizeof(buf);
cout << buf << endl; // prints the shellcode to the screen
//void *exec = VirtualAlloc(0, shellcodesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//memcpy(exec, buf, shellcodesize);
//((void(*)())exec)();
}
int main()
{
decrypt_run();
return 0;
}
when uncommenting the last three lines in decrypt_run()
the program finishes without any output other than the shellcode it self
Again the same shellcode in the out.txt
is used with example.cpp
and it runs flawlessly but not with example2.cpp
Solution 1:
In the first case, you are hard-coding the shellcode in a fixed memory buffer, and then copying those bytes as-is into your allocated executable memory. Which is fine.
But in your second case, you have a dynamic vector
filled with the (decrypted) shellcode bytes, and then you are allocating a dynamic array using non-standard VLA syntax, copying the shellcode into that array, and then copying the shellcode from that array into your executable memory. That intermediate array is completely unnecessary and should be removed, you can copy the shellcode bytes directly from the vector
into the executable memory, eg:
void decrypt_run(){
std::vector<unsigned char> decrypted(encrypted.size());
// the encrypted cipher get decrypted and the vector decrypted is filled with unsigned chars
// passing the vector to memcopy
unsigned char *buf = decrypted.data();
size_t shellcodesize = decrypted.size();
cout << buf << endl; // prints the shellcode to the screen
void *exec = VirtualAlloc(0, shellcodesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, buf, shellcodesize);
((void(*)())exec)();
}