how detect the software the presence of a VM [closed] - virtual-machine

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am beginners in the world of virtual machines and have a small question. if a software is running on a VM (eg. VMware Player) how does it know that it is installed on a VM? Does the software get the information from the operating system or is there a direct communication between the software and the hardware (VMware Player)? thank you in advance

Unfortunately there is not an unique answer. Each virtual machine has a sort of bridge you can use but you have to write specific checks for each VM you want to detect (examples are VC++ specific but you can easily adapt them to your compiler). Note that in theory you should not be able to determine if you're running under a VM or not.
VMWare
VMWare uses IN instruction to handle guest to host communication. Normally this instruction is not available in user-mode and it throws an exception but VM handles it. If we catch the exception then we know we are not running under VMWare (or we are privileges to execute IN instruction). Second test to determine if we have privileges or we are running under WMWare is almost useless but that's standard detect code and I write it here for completeness (we just check for an expected string VMXh in EBX register, note we had to initialize some registers with required values.)
bool IsRunningInsideVmWare()
{
bool flag = true;
__try
{
__asm
{
push edx
push ecx
push ebx
mov eax, 'VMXh'
mov ebx, 0
mov ecx, 10
mov edx, 'VX'
in eax, dx
cmp ebx, 'VMXh'
setz [flag]
pop ebx
pop ecx
pop edx
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
flag = false;
}
return flag;
}
Virtual PC
Guests can use a non-existing instruction 0f3f070b to communicate with host, what you can do is then emit such instruction, VM will correctly interpret it but physical CPUs will throw an exception (which you can catch and jump over offending instruction). In this example we set EBX to a known value in the exception handler and then we can detect this scenario.
DWORD __forceinline VpcExceptionFilter(LPEXCEPTION_POINTERS ep)
{
ep->ContextRecord->ctx->Ebx = -1;
ep->ContextRecord->ctx->Eip += 4;
return EXCEPTION_CONTINUE_EXECUTION;
}
bool IsRunningInsideVpc()
{
bool flag = false;
__try
{
_asm
{
push ebx
mov eax, 1
mov ebx, 0
__emit 0Fh
__emit 3Fh
__emit 07h
__emit 0Bh
test ebx, ebx
setz [flag]
pop ebx
}
}
__except(VpcExceptionFilter(GetExceptionInformation()))
{
}
return flag;
}
VirtualBox
To detect VirtualBox is extremely simple, you just need to check if a pseudo-device \\.\VBoxMiniRdrDN exists:
bool IsRunningInsideVirtualBox()
{
HANDLE handle = CreateFile("\\\\.\\VBoxMiniRdrDN", GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle != INVALID_HANDLE_VALUE)
{
CloseHandle(handle);
return true;
}
return false;
}
Something little bit more generic can be done (assumption: you're running on Windows) using WMI and the following queries:
In Win32_BaseBoard matchName against (?i)(Hyper-V|Virtual Machine|Microsoft|VMware|VirtualBox|Parallels Virtual).
In Win32_ComputerSystem match Model and Manufacturer against (?i)(Hyper-V|Virtual Machine|VMware|VirtualBox).
In Win32_VideoController match Name against (?i)Hyper-V.
CPUID instructions can also help you (when those values are supported).
With EAX set to 0 (Get vendor ID) you get in EBX, EDX and ECX an ASCII string with CPU vendor name (see Wikipedia for list). Of course a VM can return a false name or it may be an unknown VM.
With EAX set to 1 (Processor Info and Feature Bits) bit 31 of ECX (hypervisor) is set to 1 if you're running under a VM. Again a VM may return a false result (and some VMs don't honor this bit).
When I had to play with this issue I tried also to check for hardware tricks/features which are not supported in a VM (for example to USB Legacy support) but I found it's not reliable enough to be used in production.
In comment you said you're running on Android. That's a completely different story but common techniques are similar to what I said about WMI (or a combination of the above). A common way is to check the device name string for well-known emulators, from Android 7 there is a specific flag ro.kernel.qemu.
Can you fake those values? Yes, see for example Is there a way to set ro.kernel.qemu to 0 in a emulator?. Note that any decent application which cares to stop you to use it under emulation will also use multiple detection techniques (see also Android: Get Hardware Information Programmatically).

I don't think that it does matter for the software where it is running as long as it works properly.
If you really want to check if you are running (or if your self-written code) is running on VM. In Windows case it is possible to check the hardware in device manager (Windows case), because VM apps create some virtual hardware. For example VMWare will create some hardware named VMware... devices.

Related

Accepts and displays one character of 1 through 9 using assembly code in c

Can someone please explain me each line of this assembly code?
void main(void){
_asm{
mov ah,8 ;read key no echo
int 21h
cmp al,‘0’ ;filter key code
jb big
cmp al,‘9’
ja big
mov dl,al ;echo 0 – 9
mov ah,2
int 21h
big:
}
}
PS: I am new to assembly in c/c++.
Per the docs, the return value is in al, not ah. That's why it compares to al.
Edit: Adding more detail:
Looking at this code:
mov ah,8 ;read key no echo
int 21h
Think of this like a function call. Now normally a function call in asm looks like call myroutine. But DOS used interrupts to allow you to call various operating system functions (read a key from the keyboard, read data from a file, etc).
So, executing the int 21h instruction called the operating system. But how was the operating system supposed to know which OS function you wanted? Typically by putting a value in ah. If you search, you can find a number of resources that show listings of all the int 21h functions (like this). The numbers on the right are the values you put in ah.
So, mov ah,8 is preparing to call the "Wait for console input without echo" function. mov ah,2 is "Display output." Other registers are used to pass various parameters to the function being called. You need to read the description of the specific interrupt to understand what goes where.
Note that NONE of this is related to "writing inline asm in C." This is just how to call OS function from C code running under DOS. If you aren't running under DOS, int 21 won't work.

PC value in between two instructions (program counter)

Trying to understand the cause of the watchdog. The snippet of assembly routine is as follows:
fe813cf0: 2820 cmp r0, #32
fe813cf2: dbf0 blt.n fe813cd6 <XYZ+0x10>
fe813cf4: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
fe813cf8: bd10 pop {r4, pc}
My PC value from dump is fe813cf3. What does this mean? How should I interpret it?
Please let me know if more info is required.
If it's a watchdog that triggers, that seems to indicate that the processor has hung. The state you're capturing might be corrupt, in the worst case. Not sure how you get the "dump", so it's hard to tell.
In general on ARM, an odd address indicates a jump that wanted to switch to the Thumb instruction set.
See for instance this documentation of the BX (branch exchange) instruction:
The BX instruction branches to the address contained in a specified register. The value of bit 0 of the branch address determines whether execution continues in ARM state or Thumb state.
Bit 0 of an address can be used in this way because:
All ARM instructions are word-aligned. This means that bits 0 and 1 of the address of any ARM instruction are ignored because these bits refer to the halfword and byte part of the address.
All Thumb instructions are halfword-aligned. This means that bit 0 of the address of any Thumb instruction is ignored because it refers to the byte part of the address.
However, I'm pretty sure the above implies that the PC is never actually set to an odd address, bit 0 is cleared by the branch instruction.

How do I get started with ARM on iOS?

Just curious as to how to get started understanding ARM under iOS. Any help would be super nice.
In my opinion, the best way to get started is to
Write small snippets of C code (later Objective-C)
Look at the corresponding assembly code
Find out enough to understand the assembly code
Repeat!
To do this you can use Xcode:
Create a new iOS project (a Single View Application is fine)
Add a C file scratchpad.c
In the Project Build Settings, set "Generate Debug Symbols" to "No"
Make sure the target is iOS Device, not Simulator
Open up scratchpad.c and open the assistant editor
Set the assistant editor to Assembly and choose "Release"
Example 1
Add the following function to scratchpad.c:
void do_nothing(void)
{
return;
}
If you now refresh the Assembly in the assistant editor, you should see lots of lines starting with dots (directives), followed by
_do_nothing:
# BB#0:
bx lr
Let's ignore the directives for now and look at these three lines. With a bit of searching on the internet, you'll find out that these lines are:
A label (the name of the function prefixed with an underscore).
Just a comment emitted by the compiler.
The return statement. The b means branch, ignore the x for now (it has something to do with switching between instruction sets), and lr is the link register, where callers store the return address.
Example 2
Let's beef it up a bit and change the code to:
extern void do_nothing(void);
void do_nothing_twice(void)
{
do_nothing();
do_nothing();
}
After saving and refreshing the assembly, you get the following code:
_do_nothing_twice:
# BB#0:
push {r7, lr}
mov r7, sp
blx _do_nothing
pop.w {r7, lr}
b.w _do_nothing
Again, with a bit of searching on the internet, you'll find out the meaning of each line. Some more work needs to be done because make two calls: The first call needs to return to us, so we need to change lr. That is done by the blx instruction, which does not only branch to _do_nothing, but also stores the address of the next instruction (the return address) in lr.
Because we change the return address, we have to store it somewhere, so it is pushed on the stack. The second jump has a .w suffixed to it, but let's ignore that for now. Why doesn't the function look like this?
_do_nothing_twice:
# BB#0:
push {lr}
blx _do_nothing
pop.w {lr}
b.w _do_nothing
That would work as well, but in iOS, the convention is to store the frame pointer in r7. The frame pointer points to the place in the stack where we store the previous frame pointer and the previous return address.
So what the code does is: First, it pushes r7 and lr to the stack, then it sets r7 to point to the new stack frame (which is on the top of the stack, and sp points to the top of the stack), then it branches for the first time, then it restores r7 and lr, finally it branch for the second time. Abx lr at the end is not needed, because the called function will return to lr, which points to our caller.
Example 3
Let's have a look at a last example:
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
The assembly code is:
_swap:
# BB#0:
ldr r2, [r0]
ldr r3, [r1]
str r3, [r0]
str r2, [r1]
bx lr
With a bit of searching, you will learn that arguments and return values are stored in registers r0-r3, and that we may use those freely for our calculations. What the code does is straightforward: It loads the value that r0 and r1 point to in r2 and r3, then it stores them back in exchanged order, then it branches back.
And So On
That's it: Write small snippets, get enough info to roughly understand what's going on in each line, repeat. Hope that helps!

ARM BLX Instruction Range (absolute)

I got a question about the ARM BLX instruction, specifically regarding BLX RX instruction. On the ARM manual it states that for BLX label, label should be within the 32MB range. In my code, I set the R0 register to point to address1. The distance between my current address and address1 (the destination address) is about 0x05000000.
When I reach the instruction, it crashes (the code in address1 is ARM so no problems with T-mode). Is there any limit when using absolute values with BLX? Should I use veneers?
Thanks!
You can use any address as the RX register in the form BLX RX. It will perform the actions described in the arm arm.
if ConditionPassed(cond) then
target = Rm
LR = address of instruction after the BLX instruction
CPSR T bit = target[0]
PC = target AND 0xFFFFFFFE
If none of the code, calling or code being called is thumb mode then you are probably fine, make sure in that case the lsbit of the address you give it is a zero. You need to actually have code at 0x05000000 and needs to be code intented to handle a branch-link, meaning it maintains the link register (r14) if it makes more bl style calls. Likewise if you are making this blx call inside a function that was called from someone else you need to preserve r14 before making the blx call and restore r14 and or do whatever to put that value back in r15 (pc) when returning from your function.
A code example or snippets of the disassembly/objdump listing would be useful to further help you solve this problem. the code containing the blx and the code being called.
The limit only applies to the PC-relative branch (with the offset encoded in the instruction), not the register branch.
So the reason of the crash is something else. What is your processor? Do you actually have code at 'address1'? Where exactly does it crash?

How do I detect programmatically in which ring (-1, 0, 1, 2, 3) I am running?

How do I detect programmatically in which ring (-1, 0, 1, 2, 3) I am running?
The easiest way is, to just run the (x86) command and catch the corresponding error.
E.g. (SEH, Windows, kernel mode)
bool ring_lower_0 = false;
__try
{
__asm { <cmd> };
ring_lower_0 = true;
}
__except( GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION )
{
ring_lower_0 = false;
}
Notes:
cmd, is an assembler command. See the Intel Architecture Reference Manuals for a list of commands and their respective Ring levels.
Linux has a slightly different concept.
But remember that VMs residing on a lower level may mask the result by emulating the call.
(NB: The Job of the VM is to translate the invalid instruction into an meaningful call)
If you really want to check if your a virtualized and want to stop execution because of this, you should read what has been written about 'Red pill'.
Unless you're a device driver, you'll always be running in Ring 3 (for systems that have "rings", per se).
Normally i would write that you should read about "protected mode programming". There is an article about how to intertact with ring 0 using windows XP SP2. Note that it will change for others windows versions and for sure others operational systems.
http://www.codeproject.com/KB/threads/MinimalisticRingZero.aspx
If you just want to detect if you are running inside of a virtual machine, to avoid that people debug your application, for example, you can check here:
http://www.codeproject.com/KB/system/VmDetect.aspx
The ring are the lower two bits of the code segment selector (CS) register in the 64-bit x86 architecture.
You can extract it like this: (test it online)
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint64_t rcs = 0;
int ring;
asm ("mov %%cs, %0" : "=r" (rcs));
ring = (int) (rcs & 3);
printf("Hello, world. This program is running on ring %d!\n", ring);
return 0;
}
The problem with that code is that it will always return 3, because your code will always run on ring 3. To see that changing you need to create a Linux Kernel Module or Windows Device Driver.
I have a github repo where i was playing around with this in Ubuntu 18.
In the demo 1 I have the exact same code as above. You can run it:
cd demo-1
. c-build.sh
In the demo-2 I have a Linux Kernel module that will execute the same code, but inside the kernel in ring 1:
link to code:
...
#define EXAMPLE_MSG "Hello, World. This is executed in ring: _ \n"
...
uint64_t rcs = 0;
asm ("mov %%cs, %0" : "=r" (rcs));
msg_buffer[MSG_BUFFER_LEN - 3] = (int) (rcs & 3) + '0';
You cannot do printf to the console from the kernel driver. Instead you need to open the device as a file and read from it:
cat /dev/lkm_example
I would recommend you to follow the readme step by step, so you can see it running :)