Getting a string using inline ASM - c++

What I am doing is injecting a DLL into a running process. I then proceed to check some informations about that process, such as versions etc. My problem is I cannot seem to access a string in the assembly file, that contains the revision number I want to doublecheck. Here is what I have so far:
__declspec(naked) void CheckBuild()
{
char* revision;
__asm {
sub esp, __LOCAL_SIZE
pushad
pushfd
mov revision, dword ptr 0x5F5200
}
printf("Detected revision ID: %u\n", revision);
__asm {
popfd
popad
add esp, __LOCAL_SIZE
retn
}
}
For this training stuff, the address of the string, that I get through IDA and that I checked using CheatEngine and OllyDbg, is constant.
However, no matter what I try, I always get 0x5F5200 back in decimal, which is definitely not what I expect. I almost tried everything, including lea and others, but I still don't get the valid string.
Can anyone point me to the correct direction ?

you are missing the "dereferencing":
mov revision, dword ptr [0x5F5200]
which isn't a valid instruction since it has two indirects, so
mov eax, dword ptr [0x5F5200]
mov revision, eax
if the value is indeed a string, there's something else wrong:
if the string is stored at 0x5F5200, you would simply use
printf("Detected revision ID: %s\n", 0x5F5200)
if the address of the string is stored at 0x5F5200, you would use
printf("Detected revision ID: %s\n", revision)
String format
If the string is unicode, you would use
printf("Detected revision ID: %S\n", revision);
(note that with wprintf, it's the other way 'round: %s for a wide character string, and %s for a char string).
Finally, if the string is not guaranteed to be zero-terminated but has a fixed length, you need to copy from the address to a local buffer and ensure zero termination before the print.

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!

C/C++ DWORD to BYTE and BYTE to DWORD conversion in Three-Dimensional Array

I am struggling to understand if I am doing this the correct way and if this is the (only) best solution.
The project I am working on is using a Three-Dimensional Array to hold and use lots of data. One part of the "data" is DWORD type and I must have a safe conversion from/to DWORD/BYTE.
The BYTE (c style) array looks like this:
BYTE array_data[150][5][255] =
{
{
{ // bytes },
{ 0x74,0x21,0x54,0x00 }, // This is converted from DWORD like: 0x00542174
{ // bytes },
{ // bytes },
{ // bytes },
},
};
The (only) way to convert from DWORD to BYTE(s) I found:
DWORD dword_data;
char byte_array[4];
*(DWORD*)byte_array = dword_data; // byte_array becomes {0x74, 0x21, 0x54, 0x00}
wchar_t temp[256];
wsprintfW(temp, L"{0x%02x,0x%02x,0x%02x,0x%02x}, // This is converted from DWORD like: 0x%.8X\n", (BYTE)byte_array[0], (BYTE)byte_array[1], (BYTE)byte_array[2], (BYTE)byte_array[3], (DWORD)dword_data);
From I understand DWORD is 4 BYTE so that's why the char max length is 4. (correct me if I`m wrong?)
Then to convert back to DWORD from BYTE(s):
//Convert an array of four bytes into a 32-bit integer.
DWORD getDwordFromBytes(BYTE* b)
{
return (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
};
printf("dword_data: 0x%.8X\n", getDwordFromBytes(array_data[0][1]));
Which prints out fine: 0x00542174.
So my question is, is all this correct and safe ? Because I will have lots of data in the array and the DWORD/BYTE conversion for me is imperative, it must be accurate.
Please advise and correct me where I`m doing things wrong, I would very much appreciate it!
This code
DWORD dword_data;
char byte_array[4];
*(DWORD*)byte_array = dword_data;
is undefined behavior according to the C++ standard. Some compilers may allow it as an extension, but unless you want to be surprised when you change a compiler or command line options, don't use it.
The correct way is:
DWORD dword_data;
BYTE byte_array[sizeof(DWORD)];
memcpy(byte_array, &dword_data, sizeof(DWORD));
Don't worry about efficiency: this memcpy will be optimized out by any decent compiler.
In C++20 you'll be able to be more eloquent:
auto byte_array = std::bit_cast<std::array<BYTE, sizeof(DWORD)>>(dword_data);
The backwards conversion should also be done using memcpy to be endianness-independent: your getDwordFromBytes will fail to produce the original dword_data on a big-endian machine.
DWORD is 32-bit unsigned integer.
typedef unsigned long DWORD, *PDWORD, *LPDWORD;
32-bit means 4 bytes, because each byte is 8 bit. And 4*8=32
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/262627d8-3418-4627-9218-4ffe110850b2
The problem will happen when you send your byte array to some code that expects to see those bytes in reversed order (different endianness). You would then need to reverse it.
DWORD is windows specific typedef, and all windows are little-endian, so I think it's safe to use this code as is, if you process data on the same machine.

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.

DB ASM variable in Inline ASM C++

I'm trying to figure out how to use DB variables from ASM into Inline ASM C++
I have this ASM code:
filename db "C:\imagen.bmp"
eti0:
mov ah,3dh
mov al,0
mov dx,offset filename
int 21h
and in C++:
//ASCII of C:\imagen.bmp plus zero in the end because of int 21h
int filename=6758921051099710310111046981091120;
asm{
mov ah,3dh
mov al,0
mov dx,offset filename
int 21h
}
Is this is correct?
The type int can only hold a 16-bit signed integer and the number you tried to assign to filename is way outside its range. As int variables are two bytes long, they're not all that useful for storing file names. Instead you should store the name in an array of char like this:
char filename[] = "C:\\imagen.bmp";
The array will include a zero byte as its final element, as normal for strings in C++.
You could also replace entire thing with:
int handle;
_dos_open("C:\\imagen.bmp", 0, &handle);

Working with strings, char array, c++ and assembly. Issue passing string to assembly

I am working on a C++ and external asm code. It is a requirement for us to work with external ASM libraries. The problem is that, I am having difficulty passing the string from the c++ side to asm. I am sure I am making some mistake in accessing the string on the asm end.
I basically read from a text file, word - by - word. Then I want to pass each word onto the ASM side and process it for some statistics.
Suppose I retrieved a word from the file and it is stored in
string wordFromFile = "America";
processWord(wordFromFile, wordFromFile.size()) //processFromWord is the ASM side function
;;ASM SIDE
;;The doubt I have (first of all all) is how do I declare the arguments on the ASM SIDE
ProcessWordUpperCase PROC C, wordFile :BYTE, len :DWORD
OR
ProcessWordUpperCase PROC C, buffer :DWORD, len :DWORD
How should I? And one more thing, in the function I am going to access the string by each letter. What do you advise here?
Here is a skeleton just counting the length of the string where you could put youir code.
toupper.cpp
extern "C"
{
int ProcessWordUpperCase(const char *wordFile, int arraySize);
};
int main(int argc, char*arg[])
{
char t[100];
int res;
res = ProcessWordUpperCase(t, sizeof(t));
std::string s = "myvalue";
res = ProcessWordUpperCase(s.c_str(), s.length());
return 0;
}
toupper.asm
.486
.model flat, C
option casemap :none
.code
ProcessWordUpperCase PROC, wordFile:PTR BYTE, arrayLen:DWORD
LOCAL X:DWORD
push ebx
push esi
push edi
mov edi, wordFile
xor eax, eax
dec edi
dec eax
##StringLoop:
inc edi
inc eax
cmp byte ptr [edi], 0
jne ##StringLoop
; return length of string
pop edi
pop esi
pop ebx
ret
ProcessWordUpperCase ENDP
END
A simple trick to get the skeleton of a function is to tell VS to output ASM files.
How to do it:
Crete a new source file with an empty function that has the prototype you want
e.g. int foo(const char* s, int bar) { return *s + bar; }
Right click on the a source file and select Properties->C/C++->Output Files->Assembler Output.
Select a value that suits you.
build and look at the generated ASM file.
The generated asm file includes some security checks that can disable by playing with the compilation flags for this file.
From the C side:
I'd do it like that: pass the string as an array, alongside with a number of fields in the array. The program will write the pointer to the very beginning of the array to the stack, so if you want to retrieve the very first char in the string, just refer to it as
mov eax, [adress of the pointer on stack]