In my code example, I hardcoded my shellcode, and execution works fine:
std::string(buffer) = "\x48\x31\xc9\x48\x81\xe9\xc6\xff\xff ..snip..";
PUINT8 shellcode = new UINT8[buffer.size()];
RtlCopyMemory(shellcode, buffer.data(), buffer.size());
std::cout << shellcode;
// To DO
In my second code example, I just added a Caesar cipher decoder with my shellcode encoded as a string in buffer
, however I am not sure why it is being processed differently if it's stored in my buffer
as a string/byte array just like in the first code example?
#include <windows.h>
#include <iostream>
int main(int argc, char** argv) {
std::string(buffer) = "_{7;_{64_{f<_{7;_{;4_{h<_{f9_{ii_{ii_{ii_";
for (size_t i = 0; i < buffer.size(); i )
buffer[i] -= 3;
PUINT8 shellcode = new UINT8[buffer.size()];
RtlCopyMemory(shellcode, buffer.data(), buffer.size());
std::cout << shellcode;
delete[] shellcode;
return 0;
}
CodePudding user response:
Your Caesar-decoded shellcode does not match your hard-coded shellcode, that is why you are getting different outputs.
Let's look at the first character as an example, but this applies to the whole data as a whole:
Your Caesar-encoded string begins with the ASCII _
character, which has a hex value of 0x5F
. When decremented by 3, that becomes the hex value 0x5C
, which is the ASCII \
character.
However, your hard-coded shellcode begins with the ASCII H
character, which has a hex value of 0x48
. Whether you left-shift (decrement) that value by 3, or right-shift (increment) it by 3, the result won't come close to being near 0x5C
or 0x5F
. Left-shifted, 0x48
will be 0x45
(E
). Right-shifted, it will be 0x4B
(K
).
Which means that your Caesar-encoded string is the wrong encoding of your desired shellcode to begin with.