How to run machine code as a function in c++ - c++

system: Windows 10
compiler: MinGW
error: Segmentation fault
I'm trying to run machine code as a function in c++. Here is my code:
#include <iostream>
int main()
{
int(*fun_ptr)(void) = ((int(*)())("\xB8\x0C\x00\x00\x00\xC3"));
std::cout << fun_ptr();
return 0;
}
In online compilers like ideone.com program succesfully print 12 and exits. In my computer I receive "Segmentation fault" error. Can anyone help me?

A string literal such as "\xB8\x0C\x00\x00\x00\xC3" is an object of static storage duration [lex.string]/15. A compiler will typically place such string literal objects in the .rdata section of your binary, i.e., into read-only, non-executable memory. As a consequence, trying to execute the bytes of a string literal will result in an access violation. If you want to execute machine code bytes contained in a global array object, you have to make sure your object is allocated in a section that is executable. For example (targeting Windows with Visual C++):
#include <iostream>
#pragma section("runstuff", read, execute)
__declspec(allocate("runstuff"))
const unsigned char code[] = {
0xB8, 0x0C, 0x0, 0x0, 0x0, 0xC3
};
int main()
{
auto fun_ptr = reinterpret_cast<int(*)()>(&code[0]);
std::cout << fun_ptr();
return 0;
}
Note that stuff like that is inherently not portable and has implementation-defined behavior at best. If you know at build time what machine code you want to run, consider using an assembler and just linking the resulting object file to your executable. If you want to dynamically generate machine code on Windows, you will have to allocate executable memory. To do so, either create a large-enough array in executable (and also writeable) memory (e.g., analogously to my example above) into which you can place your code, or dynamically allocate executable memory, e.g. using VirtualAlloc or using HeapAlloc from a Heap with the executable flag set. You will also want to be aware of the FlushInstructionCache API…

You can do that by using an inline assembler:
#include <iostream>
int code() {
__asm (
".byte 0xB8, 0x0C, 0x00, 0x00, 0x00"
);
}
int main() {
std::cout << code() << std::endl;
return 0;
}

I found a method:
#include <iostream>
#include <windows.h>
using namespace std;
int main() {
unsigned char bytes[] = "\xB8\x0C\x00\x00\x00\xC3";
HANDLE mem_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, sizeof(bytes), NULL);
void *mem_map = MapViewOfFile(mem_handle, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0x0, 0x0, sizeof(bytes));
memcpy(mem_map, bytes, sizeof(bytes));
int result = ((int (*)(void))mem_map)();
cout << "argument:\n" << result << '\n';
return 0;
}

Related

How can I solve the problem when reading a registry entry?

i want to get the value from an registry entry. Here is my code:
#include <atlbase.h>
#include <atlstr.h>
#include <iostream>
#define BUFFER 8192
int main()
{
char value[255];
DWORD BufferSize = BUFFER;
RegGetValue(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName", L"ComputerName", RRF_RT_REG_SZ, NULL, (PVOID)&value, &BufferSize);
std::cout << value << std::endl;
}
My Computer name is: DESKTOP-IGW3F.
But if i run my program my output is: D
I have no idea how to fix it...i hope you can help me.
The Win32 function RegGetValue() does not exist. It is only a preprocessor macro that will resolve to either RegGetValueA() or RegGetValueW() depending on your project settings. In your case, the macro resolves to RegGetValueW(), therefore it treats the registry value as a Unicode string (2 bytes per character). But you are using a char (1 byte per character) buffer to receive the Unicode data.
To make your code work, you need to either explicitly call RegGetValueA() instead, or change your buffer type from char to wchar_t. Either way, you should also check the return value of the function.
A working example could look like this:
#include <windows.h>
#include <iostream>
int main()
{
WCHAR value[255];
DWORD bufferSize = 255 * sizeof(WCHAR);
if (!RegGetValueW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName", L"ComputerName", RRF_RT_REG_SZ, NULL, value, &bufferSize))
{
std::wcout << value << std::endl;
}
}

How to use LocalAlloc and LocalReAlloc correctly

I am going to learn how to use LocalAlloc and also LocalReAlloc of the Win32 API. I written the following code, but it gives me exceptions. I don't know what is wrong with the following code.
#include <Windows.h>
#include <iostream>
namespace code
{
namespace memory
{
void allocation()
{
char* string = reinterpret_cast<char*>(LocalAlloc(LPTR, 6 + 1));
CopyMemory(string, "WINAPI", 6);
std::printf("%s\n", string);
string = reinterpret_cast<char*>(LocalReAlloc(string, 6 + 13 + 1, LMEM_MOVEABLE));
CopyMemory(string + 6, "IS THE BEST", 13);
std::printf("%s\n", string);
delete string;
}
}
}
int main(int argc, char* argv[])
{
code::memory::allocation();
return 0;
}
When I compile the above program, it doesn't give me any error but when I run it, it gives me the exception. The following message is from the exception:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: ...Windows\00 Windows API Programming\Debug\52_DynamicMemory.exe
File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 904
Expression: _CrtIsValidHeapPointer(block)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
There are several issues with your code.
A complete lack of error handling.
If LocalReAlloc() fails, you are leaking the memory allocated by LocalAlloc().
The second CopyMemory() is exceeding the bounds of the string literal being copied. And you are not ensuring the reallocated memory is null terminated for the following printf(), were the literal being copied properly.
You are not freeing the allocated memory correctly. You must use LocalFree(), not delete.
Try this instead:
#include <Windows.h>
#include <cstdio>
#include <cstring>
namespace code
{
namespace memory
{
void allocation()
{
char* string = static_cast<char*>(LocalAlloc(LMEM_FIXED, 6 + 1));
if (!string) return;
std::strcpy(string, "WINAPI");
std::printf("%s\n", string);
char* newstring = static_cast<char*>(LocalReAlloc(string, 6 + 12 + 1, LMEM_MOVABLE));
if (!newstring) { LocalFree(string); return; }
string = newstring;
std::strcpy(string + 6, " IS THE BEST");
std::printf("%s\n", string);
LocalFree(string);
}
}
}
int main()
{
code::memory::allocation();
return 0;
}
LocalAlloc Allocates the specified number of bytes from the heap, and if fails, returns value is NULL. To get extended error information, call GetLastError.
If the LocalAlloc function succeeds, allocates at least the amount requested, and to free allocated memory call LocalFree
LocalReAlloc used to re-alloceate memory that allocated either by LocalAlloc or LocalReAlloc, note that if LocalReAlloc fails, the original memory is not freed, and the original handle and pointer are still valid.

ReadProcessMemory reads Memory backwards?

When using ReadProcessMemory to read memory of an executable file, the first two bytes that I get are reversed. The code is:
SIZE_T dataRead;
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER) malloc(1);
ReadProcessMemory(process, (LPVOID)addr, dosHeader, 2, &dataRead);
printf("%x\n", dosHeader->e_magic);
The above outputs 5A4D instead of 4D5A. Why would that be? Could it endianess?
Thanks in advance.
Yes, this is due to endianness. The first byte in the file is 0x4d, the second byte is 0x5a. When you print these using %x, they are interpreted as being a little endian number, so the bytes are swapped when they are printed. Consider, as a self-contained example, the following program:
#include <cassert>
#include <cstdio>
int main()
{
assert(sizeof(unsigned) == 4);
char bytes[4] = { 0x12, 0x34, 0x56, 0x78 };
std::printf("%x\n", *reinterpret_cast<unsigned const*>(bytes));
}
On a system with a little-endian byte ordering, the output will be 78563412. (This example program ignores potential alignment issues; since you are using Visual C++, there will be no problems.)
Note also that you are overrunning your one byte allocation (you malloc(1) but read two bytes).

memcpy - int variable to BYTE

I am trying to create a data packet, using memcpy. I expect to see the output in pOutBuffer, whose first four bytes will have 999, followed by 111 followed by 12; But currently i am getting some garbage.
The problem is that instead of copying the value, it copies the address, I think. How can i copy these values in to a contiguous memory so that i can write it to disk and can retrieve the data at the receiving end with my defined format?
Thanks.
#include "stdafx.h"
#include "windows.h"
typedef struct
{
int Begin;
int End;
int Size;
}PACKET;
void AddBuffer(PACKET* pPacket, BYTE* pOutBuffer)
{
memcpy(pOutBuffer, &pPacket->Begin, sizeof(int));
memcpy(pOutBuffer+sizeof(int), &pPacket->End, sizeof(int));
memcpy(pOutBuffer+sizeof(int)+sizeof(int), &pPacket->Size, sizeof(int));
}
int _tmain(int argc, _TCHAR* argv[])
{
PACKET* pPacket = new PACKET;
pPacket->Begin = 999;
pPacket->End = 111;
pPacket->Size = 12;
BYTE* pOutBuffer = new BYTE [pPacket->Size];
AddBuffer(pPacket, pOutBuffer);
//Write pOutBuffer on to the disk
//WriteFile(vhFileToWrite,(BYTE*)pOutBuffer,pPacket.Size,&vRetFileSize,NULL);
//Delete pOutBuffer
return 0;
}
Source sample has been updated. It now builds ok
Your code works correctly. On a little-endian machine with sizeof(int)==4, the number 999 will be stored as the four bytes 0xe7, 0x03, 0x00, 0x00.
You said you saw the character 'ç': That is because you are trying to view the array as a string, and ç has the character code 0xe7, which is indeed the first byte written. If you view it as an array (either using Visual Studio's memory view, or by typing pOutBuffer,12 in the watch window), you will see the correct byte values.

Modifying binary files

I'm trying to write a small program which will search a binary file for a few bytes and replace these with another bunch of bytes. But everytime I try running this small app I got message about istream_iterator is not dereferenceable.
Maybe someone have a suggestion how to do this in another way (iterators are a little bit a new subject for me).
#include <fstream>
#include <iterator>
#include <algorithm>
using namespace std;
int main() {
typedef istream_iterator<char> input_iter_t;
const off_t SIZE = 4;
char before[SIZE] = { 0x12, 0x34, 0x56, 0x78 };
char after[SIZE] = { 0x78, 0x12, 0x34, 0x65 };
fstream filestream("numbers.exe", ios::binary | ios::in | ios::out);
if (search(input_iter_t(filestream), input_iter_t(), before, before + SIZE) != input_iter_t()) {
filestream.seekp(-SIZE, ios::cur);
filestream.write(after, SIZE);
}
return 0;
}
This is my second attempt to do this but also something is wrong. With small files looks like works OK but with bigger (around 2MB) it works very slowly and never find pattern what I'm looking for.
#include <iostream>
#include <cstdlib>
#include <string>
#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <windows.h>
using namespace std;
int main() {
const off_t Size = 4;
unsigned char before[Size] = { 0x12, 0x34, 0x56, 0x78 };
unsigned char after[Size] = { 0x90, 0xAB, 0xCD, 0xEF };
vector<char> bytes;
{
ifstream iFilestream( "numbers.exe", ios::in|ios::binary );
istream_iterator<char> begin(iFilestream), end;
bytes.assign( begin, end ) ;
}
vector<char>::iterator found = search( bytes.begin(), bytes.end(), before, before + Size );
if( found != bytes.end() )
{
copy( after, after + Size, found );
{
ofstream oFilestream( "number-modified.exe" );
copy( bytes.begin(), bytes.end(), ostream_iterator<unsigned char>(oFilestream) );
}
}
return 0;
}
Cheers,
Thomas
Read a larger part of the file to memory, replace it in memory and then dump the bunch to the disk. Reading one byte at a time is very slow.
I also suggest you read about mmap (or MapViewOfFile in win32).
search won't work on an istream_iterator because of the nature of the iterator. It's an input iterator, which means it simply moves forward - this is because it reads from the stream, and once it's read from the stream, it can't go back. search requires a forward iterator, which is an input iterator where you can stop, make a copy, and move one forward while keeping the old one. An example of a forward iterator is a singly-linked list. You can't go backwards, but you can remember where you are and restart from there.
The speed issue is because vector is truly terrible at handling unknown data. Every time it runs out of room, it copies the whole buffer over to new memory. Replace it with a deque, which can handle data arriving one by one. You will also likely get improved performance trying to read from the stream in blocks at a time, as character-by-character access is a pretty bad way to load an entire file into memory.
Assuming the file isn't too large, just read the file into memory, then modify the memory buffer as you see fit, then write it back out to a file.
E.g. (untested):
FILE *f_in = fopen("inputfile","rb");
fseek(f_in,0,SEEK_END);
long size = ftell(f_in);
rewind(f_in);
char* p_buffer = (char*) malloc (size);
fread (p_buffer,size,1,f_in);
fclose(f_in);
unsigned char *p= (unsigned char*)p_buffer;
// process.
FILE *f_out = fopen("outoutfile","wb");
fwrite(p_buffer,size,1,f_out);
fclose(f_out);
free(p_buffer);