Convert Extern C to Inline ASM - c++

I have a C++ project that calls a extern function located in a .asm (MASM) file. Is there any way I can inline the MASM code inside of the C++ file instead of having to having to use a seperate .asm file?
.asm file
.data
.code
ZwReadVirtualMemory proc
mov r10, rcx
mov eax, 3Fh
syscall
ret
ZwReadVirtualMemory endp
end
Here is the C++ file
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
extern "C" NTSTATUS ZwReadVirtualMemory(HANDLE hProcess, void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead = NULL);
int main() {
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 14648);
if (!hProcess)
return EXIT_FAILURE;
int intBuffer = 0;
void* lpBaseAddress = 0;
SIZE_T lpNumberOfBytesRead = 0;
NTSTATUS status = ZwReadVirtualMemory(hProcess, (PVOID)0x10ad0000, &intBuffer, sizeof(int), &lpNumberOfBytesRead);
cout << "ZwRVM returned " << dec << status << endl;
cout << "intBuffer = " << dec << intBuffer << endl;
cout << "lpNumberOfBytesRead = " << lpNumberOfBytesRead << endl;
cin.get();
}

Certain C/C++ compilers support non-standard inline assembly blocks asm or __asm__. They can be used to incorporate portions of assembler code into regular functions or methods.
Your code sample clearly points at using a WinAPI (thus Windows as target platform) and Visual Studio as a compiler (stdafx.h being the most unportable piece). However, Visual Studio 2010 and later updates stopped supporting inline assembly for 64-bit targets: http://msdn.microsoft.com/en-us/library/4ks26t93%28VS.100%29.aspx
Your options:
Compile MASM file into a separate object file and link it later with the rest of the program.
Use Intel Compiler for Windows. It supports inline assembler and is meant to be a drop-in replacement for Microsoft compilers on Windows, however I do not know how much extra porting effort will be required.
The only bit from your assembler file that is not directly accessible from C/C+ is issuing the syscall machine instruction. If you find an intrinsic function for that instruction that is supported by MS VS, you can use it instead of an inline assembly block. However, I cannot find one here. Intel's intrinsics are no better.

Related

Print assembly variable C++

Hello All!
I'm doing a MASM course and I got into this exercise.
I have this simple assembly code:
.386
.model flat,c
.data
quote byte "Machines do feel", 0
message byte SIZEOF quote DUP(0),0
.code
start proc
mov esi,0
mov ecx,SIZEOF quote
LP:
mov al,quote[esi]
mov message[esi],al
inc esi
loop LP
ret
start endp
end
And I want to write a C++ program that can "printf" the variable "message".
How can I do this?
I tryed to add:
mov eax, DWORD ptr [message]
To the ".asm" file to store the address of the message variable on the register returned by the function and then I wrote this program to try to printf the values:
#include <iostream>
extern "C" char *start();
int main(){
char *message = start();
for(int i = 0x0; i < sizeof(message)/sizeof(char); i++){
printf("%s", message[i]);
}
return 0x0;
}
But when I try to run it I get the error:
Unhandled page fault on read access to 6863614D at address 0040162E (thread 0024), starting debugger...
0024:err:seh:start_debugger Couldn't start debugger L"winedbg --auto 32 68" (2)
Can you please explain me how can I print the values of the ".asm" file "message" variable?
And can also show me different methods to do this?
Thank you so much, have a nice coding!

Question on querying memory regions (Windows)

I had written a program that enumerates all the memory regions of a process with the following attributes: MEM_COMMIT and PAGE_READWRITE, and that at the end of the program prints the total size of all the regions found, everything seems to work well, then I tried it on programs at 64 bits and it turned out that the total regions size was greater than the RAM available on my PC.
On my PC there are 15.9GB of RAM available while one of the scans that I made was 18.363.846.656 Byte (18.3 GB).
I wonder, how is it possible? is it a mistake in my code, or are they using some memory management methods that I am not aware of?
#include <iostream>
#include <Windows.h>
int main()
{
// Get an handle to the process
HWND hWnd = FindWindowA(NULL, "WindowName");
DWORD pid; GetWindowThreadProcessId(hWnd, &pid);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
// Declaration of some variables
char* Ptr(0);
MEMORY_BASIC_INFORMATION Mem;
size_t totalSize = 0;
// Start querying
while (VirtualQueryEx(hProcess, Ptr, &Mem, sizeof(MEMORY_BASIC_INFORMATION)))
{
if (Mem.State == MEM_COMMIT && Mem.Protect == PAGE_READWRITE)
{
totalSize += Mem.RegionSize;
std::cout << std::hex << Mem.BaseAddress << " - " << (LPVOID)(Mem.RegionSize + (INT64)Mem.BaseAddress) << " - size:(" << std::dec << Mem.RegionSize << ")\n";
}
Ptr += Mem.RegionSize;
}
std::cout << "[" << totalSize << "]";
CloseHandle(hProcess);
return 0;
}
You cannot query physical memory using any normal documented Windows API functions. Virtual Memory is intended to be an abstraction, the Operating System is meant to handle all this in the background for you.
There is RAMMap from SysInternals which can display information regarding physical memory but the source code is not public. RAMMap is explained in this video from Microsoft
To learn more about how the system works you can look up "physical memory" in the Windows Internals book.
There is some code in this answer which claims to be able to query physical memory from usermode here using NtOpenSection and NtMapViewOfSection.
To interact with physical memory from a kernel driver you can read this source code

How to run machine code as a function in 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;
}

Generate self-contained assembly subroutines with call to Windows API functions from C/C++

I have done some experiments with shellcode execution in which I wrote my own shellcode, write it into the target program's memory in which I want it executed and execute it with either a new thread or thread hijacking.
This works well, but manually writing the shellcode is rather time consuming, therefore I am looking for a method to be able to write a function in C or C++ that will be completely self-contained once compiled. This means that any compiled function should be executable independently. This way I could directly write it into my target's program ready to execute with WriteProcessMemory for example. Pushing the shellcode would therefore be done with a code like this:
#include <Windows.h>
#include <iostream>
using namespace std;
BOOL MakeABeep() {
return Beep(0x500, 0x500);
}
DWORD MakeABeepEnd() { return 0; }
int main() {
DWORD pid = 0;
cout << "PID: ";
cin >> dec >> pid;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hProcess) { cout << "OpenProcess failed GLE = " << dec << GetLastError() << endl; return EXIT_FAILURE; }
void* buf = VirtualAllocEx(hProcess, NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!buf) { cout << "VirtualAllocEx failed GLE = " << dec << GetLastError() << endl; return EXIT_FAILURE; }
SIZE_T size = (DWORD64)MakeABeep - (DWORD64)MakeABeepEnd;
BOOL wpmStatus = WriteProcessMemory(hProcess, buf, MakeABeep, size, NULL);
if (!wpmStatus) { cout << "WriteProcessMemory failed GLE = " << dec << GetLastError() << endl; return EXIT_FAILURE; }
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)buf, NULL, NULL, NULL);
if (!hThread) { cout << "CreateRemoteThread failed GLE = " << dec << GetLastError() << endl; return EXIT_FAILURE; }
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, buf, 0, MEM_RELEASE);
return EXIT_SUCCESS;
}
If compiled with the default options of MSVC compiler, only a bunch of jmp instructions are copied, which seem to be a jump table. To avoid this problem, I disabled incremental linking in the compiler options and now any code in the function MakeABeep is properly copied, with the exception of calls to imported functions.
In my shellcode I pass the arguments as required by the calling convention and then I put the address of the function I want to call in the register rax and finally I call the function with call rax.
Is it possible to make the compiler generate something like that?
The key thing is that the generated binary has to have self-contained-only subroutines that could be executed independently.
For example, this is the assembly code generated for the function MakeABeep:
To be able to run it directly, instead of this mov rax, QWORD PTR [rip+0x?] the compiler should mov the full address of the Beep function into rax instead.
Please ignore the problems related to the modules possibly not loaded or loaded at a different address in the target program, I only intent to call functions in kernel32 and ntdll which are for sure loaded and at the same address in different processes.
Thank you for your help.
The compiler does not know the full address of the Beep function. The Beep function lives in kernel32.dll and this .DLL is marked as ASLR compatible and could in theory change its address every time you run the program. There is no compiler feature that lets you generate the real address of a function in a .DLL because such a feature is pretty useless.
One option I can think of is to use magic cookies that you replace with the correct function addresses at run time:
SIZE_T beepaddr = 0xff77ffffffff7001ull; // Magic value
((BOOL(WINAPI*)(DWORD,DWORD))beepaddr)(0x500, 0x500); // Call Beep()
compiles to
00011 b9 00 05 00 00 mov ecx, 1280 ; 00000500H
00016 48 b8 01 70 ff ff ff ff 77 ff mov rax, -38280596832686079 ; ff77ffffffff7001H
00020 8b d1 mov edx, ecx
00022 ff d0 call rax
You would then have to write a wrapper around WriteProcessMemory that knows how to lookup and replace these magic values with the correct address.
Some shell code will have its own mini implementation of GetModuleHandle and GetProcAddress where it looks up the module in the PEB module list and then searches the export directory. They often use a mini hashing function for the names so they don't have to deal with strings.
If you are injecting a large amount of code you will probably get tired of these hacks and just load a .DLL in the remote process like everyone else.

Calling Fortran from C++; String on return corrupted

I am calling a Fortran 77 Function from C++ that passes a file handle, a string, and the length. The files opens successfully and the Fortran subroutine exits. However, back in the C++ Code the string, which was passed to fortran, is corrupted. When the bottom of the function openFile is reached the program crashes.
The crash only appears in release but not in debug. Plotting the strings, I see that in release the variable fileNameToFortran is full of trash.
Thanks for your help
I use ifort with following compiler flags in release (windows 7 machine (32 bit)):
/names:lowercase /f77rtl /traceback /iface:cref /threads /recursive /LD
and in debug:
/names:lowercase /f77rtl /traceback /iface:cref /threads /recursive /LDd /Zi /debug:full /check:all /traceback
Here is the C-Code:
typedef void (FORTCALL *sn_openfile_func) (int *,
char[],
int *,
int);
void openFile(const int fileHandle, const std::string fileName)
{
int fileHandleToFortran = fileHandle;
char fileNameToFortran[20];
assert(fileName.size() < 20);
strcpy(fileNameToFortran, fileName.c_str());
int lstr = strlen(fileNameToFortran);
openfile_func_handle(&fileHandleToFortran, fileNameToFortran, &lstr, lstr);
}
Here is the Fortran Code:
SUBROUTINE SN_OPENFILE(FILENR,FILENAME,FSIZE)
!DEC$ ATTRIBUTES DLLEXPORT :: SN_OPENFILE
IMPLICIT NONE
INTEGER FILENR, FSIZE
CHARACTER FILENAME*FSIZE
OPEN (FILENR,FILE = FILENAME,
& ACCESS = 'SEQUENTIAL' , STATUS = 'REPLACE', ERR=222)
GOTO 333
222 WRITE(*,*) 'Error opening file'
333 END
OK, I found the answer myself.
The macro FORTCALL was defined as __STDCALL
Now, when using iface:cref it only crashes in release. That is strange, but after I have removed it, it works for release and debug.