Onvif device not found by Onvif device manager - web-services

I'm trying to implement a camera device server with onvif profile s standards using gsoap. on ws dynamic discovery, when I tried to run code in https://github.com/mpromonet/ws-discovery/blob/master/gsoap/server.cpp, Onvif device manager does not give any answer to my probematches message. I can see that I'm getting probe message, sending probematches messages but Onvif device manager simply neglects them.
I'm made these parameter changes for my device:
const int _metadataVersion = 1;
static const char* _xaddr= "http://10.0.0.50:1881";
const char* _type="tdn:NetworkVideoTransmitter " "tds:Device " ;
const char* _scope=
"onvif://www.onvif.org/name/ru "
"onvif://www.onvif.org/hardware/hw "
"onvif://www.onvif.org/Profile/Streaming "
"onvif://www.onvif.org/location/ANY "
"onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/type/audio_encoder onvif://www.onvif.org/type/ptz ";
const char* _endpoint="urn";
I tried many parameters but I could not find the solution. What kind of changes do i need to make, in order to be discoverable by Onvif device manager?

As you can see, the namespace you used (tdn & tds) are not declared in the generated namespaces (in gen/wsdd.nsmap) :
#include "soapH.h"
SOAP_NMAC struct Namespace namespaces[] =
{
{"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", "http://www.w3.org/*/soap-envelope", NULL},
{"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", "http://www.w3.org/*/soap-encoding", NULL},
{"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL},
{"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL},
{"wsa", "http://schemas.xmlsoap.org/ws/2004/08/addressing", NULL, NULL},
{"wsdd", "http://schemas.xmlsoap.org/ws/2005/04/discovery", NULL, NULL},
{NULL, NULL, NULL, NULL}
};
In order to specify a wsdd:ProbeType with a qualified name you should use:
"http://www.onvif.org/ver10/network/wsdl":NetworkVideoTransmitter
This can be achieved specifying the -t argument :
ws-discovery.exe -t \"http://www.onvif.org/ver10/network/wsdl\":NetworkVideoTransmitter \
-x http://10.0.0.50:1881
or modifying the code:
const char* _type="\"http://www.onvif.org/ver10/network/wsdl\":NetworkVideoTransmitter" ;

Related

how to make Google search using c++ program

I am wondering and almost searched everywhere on the web but couldn't find anything helpful. I am quite a beginner with c++. Is there any possible way to make a Web search when I type a word in console on program runtime, it should go to google.com and fetch the meaning of that word to my .txt file or directly on my console? Basically, I am trying to implement a dictionary (offline+Online) using c++ and linked lists/trees.
Any sort of help will be much appreciated.
There is a couple of steps to this that you may need to do before you even start writing the C++ code.
Note: C++ is probably not the easiest language to do this in.
You will need a google account.
Go to the website and sign up (free)
You will need to get an API Key
Go to the website and generate (free)
You will need to know the REST command to generate output.
Here the easiest thing to do is to use CURL to test your REST query (or use a tool like PostMan). Though their website provides a simple starting point to test parameters.
Once you have the rest command working on the command line. Convert this to C code using the libcurl API.
You will need to parse the returned value.
The returned value is JSON you will need to either parse this manually or use an existing library. There are several out there. I hear jsoncpp is good I prefer ThorsSerializer but I wrote that so I am biased.
Making a dictionary (non commercial).
Its probably simpler to use the MERRIAM-WEBSTER'S API rather than googles.
Step 1: Register to get an API Key
https://dictionaryapi.com/register/index
Step 2: Get The API Key
Once you have filled out the form.
And confirmed your e-mail
And Logged into dictionaryapi.com
Go to your keys page
Step 3: Verify you can get information from the command line
Documentation here
Note: My key is not going to work for you (I deleted it). You will have to create and use your own.
curl https://www.dictionaryapi.com/api/v3/references/collegiate/json/voluminous?key=568e93fa-c06f-4f96-bf12-948cf301a03f
Step 4: Convert the command line into C code.
#include <string>
#include <iostream>
#include <curl/curl.h>
extern "C" size_t write_callback(char *ptr, size_t size, size_t nmemb, void *dataFromServerVoid)
{
std::string& dataFromServer = *(reinterpret_cast<std::string*>(dataFromServerVoid));
dataFromServer.append(ptr, size * nmemb);
return size * nmemb;
}
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cerr << "Fail: Read Instructions\n";
return -1;
}
std::cout << "Dictionary:\n"
<< " Getting: " << argv[1] << "\n";
CURL* curl = curl_easy_init();
if (curl)
{
static const std::string apiKey = "?key=568e93fa-c06f-4f96-bf12-948cf301a03f";
static const std::string urlBase = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/";
const std::string url = urlBase + argv[1] + apiKey;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
// The default action is to print any data returned
// to the standard output. But we are going to need to
// processes that data so adding some functions
// and data to capture the output.
std::string dataFromServer;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &dataFromServer);
// Get the data from the server.
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
// If the call worked we can print out
// what we retrieved.
if (res == CURLE_OK) {
std::cout << " Got: >" << dataFromServer << "<\n";
}
}
}
Step 5: Build and verify it works.
> g++ -std=c++17 dict.cpp -lcurl
> ./a.out bootstrap
We get:
Dictionary:
Getting: bootstrap
Got: >[{"meta":{"id":"bootstrap:1","uuid":"9c960ec2-a3ce-4f09-a7ba-a4972036314a","sort":"020350800","src":"collegiate","section":"alpha","stems":["bootstrap","bootstraps"],"offensive":false},"hom":1,"hwi":{"hw":"boot*strap","prs":[{"mw":"\u02c8b\u00fct-\u02ccstrap","sound":{"audio":"bootst01","ref":"c","stat":"1"}}]},"fl":"noun","def":[{"sseq":[[["sense",{"sn":"1","dt":[["text","{bc}a looped strap sewed at the side or the rear top of a boot to help in pulling it on"]]}]],[["sense",{"sn":"2","ins":[{"if":"boot*straps","spl":"plural"}],"dt":[["text","{bc}unaided efforts "],["uns",[[["text","often used in the phrase {it}by one\u0027s own bootstraps{\/it}"]]]]]}]]]}],"date":"1875{ds||1||}","shortdef":["a looped strap sewed at the side or the rear top of a boot to help in pulling it on","unaided efforts \u2014often used in the phrase by one\u0027s own bootstraps"]},{"meta":{"id":"bootstrap:2","uuid":"59331df1-c1fd-44ff-bd8d-73d471ad6819","sort":"020350900","src":"collegiate","section":"alpha","stems":["bootstrap"],"offensive":false},"hom":2,"hwi":{"hw":"bootstrap"},"fl":"adjective","def":[{"sseq":[[["sense",{"sn":"1","dt":[["text","{bc}designed to function independently of outside direction {bc}capable of using one internal function or process to control another "],["vis",[{"t":"a {wi}bootstrap{\/wi} operation to load a computer"}]]]}]],[["sense",{"sn":"2","dt":[["text","{bc}carried out with minimum resources or advantages "],["vis",[{"t":"{wi}bootstrap{\/wi} efforts"}]]]}]]]}],"date":"1926{ds||1||}","shortdef":["designed to function independently of outside direction : capable of using one internal function or process to control another","carried out with minimum resources or advantages"]},{"meta":{"id":"bootstrap:3","uuid":"257edd7e-c31a-453a-a15b-e1d022c70d96","sort":"020351000","src":"collegiate","section":"alpha","stems":["bootstrap","bootstrapped","bootstrapper","bootstrappers","bootstrapping","bootstraps"],"offensive":false},"hom":3,"hwi":{"hw":"bootstrap"},"fl":"verb","ins":[{"if":"boot*strapped"},{"if":"boot*strap*ping"}],"def":[{"vd":"transitive verb","sseq":[[["sense",{"dt":[["text","{bc}to promote or develop by initiative and effort with little or no assistance "],["vis",[{"t":"{it}bootstrapped{\/it} herself to the top"},{"t":"\u2026 turns out to be pretty talented at identifying and {wi}bootstrapping{\/wi} promising creative endeavors.","aq":{"auth":"Harry McCracken"}}]]]}]]]}],"uros":[{"ure":"boot*strap*per","fl":"noun"}],"date":"1951","shortdef":["to promote or develop by initiative and effort with little or no assistance"]}]<
Step 6: Extract the data from the JSON
I am going to use ThorsSerializer to get the data. This allows de-serialization of JSON directly into C++ objects without having to parse and interpret any intermediate objects. This makes it really usefull for stable web interfaces (like most REST interfaces).
Step 6a: Install ThorsSerializer
> brew install thors-serializer
A useful tip here. To visualize and quickly see the JSON there is a great command line tool jq. if you stream JSON to this the default action is simply to prity print the JSON (though it has a lot more power)
> brew install jq
> echo "<JSON TEXT>" | jq
Step 6b: Build Definition of what you want:
Looking at the definition of JSON we only need one bit of data "shortdef" which is an array of strings inside a definition object.
// So simply declare an object like the JSON declaraition.
// You can ignore any parts of the JSON you don't want.
struct Definition
{
std::vector<std::string> shortdef;
};
// Now tell the ThorsSerializer the bits it needs to understand.
// The library already knows how to handle all the standard types.
// So no extra declarations needed for std::vector.
ThorsAnvil_MakeTrait(Definition, shortdef);
Step 6C: Write code to extract data from JSON.
using ThorsAnvil::Serialize::jsonImporter;
std::stringstream dataFromServerStream(dataFromServer);
std::vector<Definition> definition;
// ThorsSerializer works for any type of stream.
// Files are supported natively and its not hard
// to wrap sockets as a stream if you want to.
// In this case I have kept it simple.
dataFromServerStream >> jsonImporter(definition);
Step 6c: Put it all together:
#include <vector>
#include <string>
#include <iostream>
#include <curl/curl.h>
#include "ThorSerialize/Traits.h"
#include "ThorSerialize/JsonThor.h"
extern "C" size_t write_callback(char *ptr, size_t size, size_t nmemb, void *dataFromServerVoid)
{
std::string& dataFromServer = *(reinterpret_cast<std::string*>(dataFromServerVoid));
dataFromServer.append(ptr, size * nmemb);
return size * nmemb;
}
struct Definition
{
std::vector<std::string> shortdef;
};
ThorsAnvil_MakeTrait(Definition, shortdef);
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cerr << "Fail: Read Instructions\n";
return -1;
}
std::cout << "Dictionary:\n"
<< "Getting: " << argv[1] << "\n";
CURL* curl = curl_easy_init();
if (curl)
{
static const std::string apiKey = "?key=568e93fa-c06f-4f96-bf12-948cf301a03f";
static const std::string urlBase = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/";
const std::string url = urlBase + argv[1] + apiKey;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
std::string dataFromServer;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &dataFromServer);
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res == CURLE_OK) {
using ThorsAnvil::Serialize::jsonImporter;
std::stringstream dataFromServerStream(dataFromServer);
std::vector<Definition> definition;
dataFromServerStream >> jsonImporter(std::move(definition));
for(auto def: definition[0].shortdef) {
std::cout << " " << def << "\n";
}
}
}
}
Step 7: Build
g++ -std=c++17 main2.cpp -lcurl -lThorSerialize17 -lThorsLogging17
> ./a.out bootstrap
We get:
Dictionary:
Getting: bootstrap
a looped strap sewed at the side or the rear top of a boot to help in pulling it on
unaided efforts —often used in the phrase by one's own bootstraps
Just as a comparison.
The same code in Javascript. Now my javascript is not good. But this code is still tighter and more readable. So this shows that C++ is not the best language to do this as a beginner.
const fetch = require('node-fetch');
const apiKey = "?key=568e93fa-c06f-4f96-bf12-948cf301a03f";
const urlBase = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/";
const url = urlBase + process.argv[2] + apiKey;
fetch(url)
.then(res => res.json())
.then((definition) => {
for(var item in definition[0].shortdef) {
console.log(definition[0].shortdef[item]);
}
})
.catch(err => { throw err });
To run this:
> node dict.js bootstrap
But saying that. If you find an appropriate library this code can be just as concise as the Javascript. But you need an appropriate library (which may be difficult and hard to find/build and install). All of which are made easy with javascript.
Example of simple version:
#include <vector>
#include <string>
#include <iostream>
#include "ThorSerialize/Traits.h"
#include "ThorSerialize/JsonThor.h"
#include "ThorSocketStream/ThorsSimpleStream.h"
struct Definition
{
std::vector<std::string> shortdef;
};
ThorsAnvil_MakeTrait(Definition, date, shortdef);
int main(int argc, char* argv[])
{
using ThorsAnvil::Stream::IThorSimpleStream;
using ThorsAnvil::Serialize::jsonImporter;
static const std::string apiKey = "?key=key=568e93fa-c06f-4f96-bf12-948cf301a03f";
static const std::string urlBase = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/";
const std::string url = urlBase + argv[1] + apiKey;
IThorSimpleStream stream(url);
std::vector<Definition> dataFromServer;
stream >> jsonImporter(dataFromServer)
for(auto const& def: dataFromServer[0].shortdef) {
std::cout << " " << data << "\n";
}
}
But getting the SimpleStream library may take some work to build.

Find service`s uuid of a bluetooth device

I'm trying to get information about services provided by bluetooth devices. Using WSALookupServiceNext I can get list of all services. However, regardless of what bluetooth device I try to discover, the resulting WSAQUERYSET structure (pqs) never contains lpServiceClassId field (while the lpszServiceInstanceName is always present). I want to know UUID of a service to determine to which class of the Table 2: Service Class Profile Identifiers it belongs.
#include<winsock2.h>
int main()
{
WSADATA data;
WSAStartup(MAKEWORD(2, 2), &data);
WSAQUERYSET qs{};
qs.dwSize = sizeof(WSAQUERYSET);
qs.dwNameSpace = NS_BTH;
qs.dwNumberOfCsAddrs = 0;
qs.lpszContext = (LPWSTR)L"12:34:56:78:99:11";
qs.lpServiceClassId = const_cast<LPGUID>(&PublicBrowseGroupServiceClass_UUID);
const DWORD flags = LUP_FLUSHCACHE | LUP_RETURN_ALL;
HANDLE hlookup = nullptr;
WSALookupServiceBegin(&qs, flags, &hlookup);
while (true) {
char buff[4096];
WSAQUERYSET* pqs = (WSAQUERYSET*)buff;
DWORD size = sizeof(buff);
memset(buff, 0, size);
const INT res = WSALookupServiceNext(hlookup, flags, &size, pqs);
if (res != 0 && GetLastError() == WSA_E_NO_MORE) {
break;
}
// it prints "service name=Advanced Audio, service uuid=0x0"
wprintf(L"service name=%s, service uuid=0x%X\n", pqs->lpszServiceInstanceName, pqs->lpServiceClassId->Data1);
}
}
Answering my own question:
In order to get service ID we have to parse SPD structures which are returned from WSALookupServiceNext function call and accessible via WSAQUERYSET.lpBlob member.
For more details see Mike Petrichenko's comment.
Also, there is a very good example how to implement it from Qt framework source code.
As for myself, I decided not to follow this path, because my goal was to write a console utility for pairing Bluetooth devices. I have found that there is a better way to do that using Windows.Devices.Enumeration API. Finally, using this API, I managed to create the BluetoothDevicePairing utility I was working on.

Authentication against Active Directory with C++ on Linux

I'm surprised there's so few examples on this out there. I basically need to do a user/pass authentication against Active Directory. I'm able to initialize a connection to active directory, but it always gives me an "Invalid Credentials" error. I'm wondering if I'm passing it something wrong. This is my first attempt with LDAP. For that matter, I'm open to another (well documented perhaps) solution.
#include <iostream>
#include <stdio.h>
#define LDAP_SERVER "ldap://hq.mydomain.local/"
#include <ldap.h>
int main( int argc, char** argv )
{
LDAP *ld;
int version( LDAP_VERSION3 );
int rc;
char bind_dn[100];
berval creds;
berval* serverCreds;
if( ldap_initialize( &ld, LDAP_SERVER ) ) {
std::cerr << "Error initializing ldap..." << std::endl;
return 1;
}
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
creds.bv_val = "password";
creds.bv_len = strlen("password");
rc = ldap_sasl_bind_s( ld, "sAMAccountName=MYDOMAIN\\UserName,dc=mydomain,dc=local", "GSSAPI", &creds, NULL, NULL, &serverCreds );
if ( rc != LDAP_SUCCESS ) {
std::cerr << "ERROR: " << ldap_err2string( rc ) << std::endl;
return 1;
} else {
std::cout << "Success." << std::endl;
}
return 0;
}
EDIT:
I wanted to make sure everything is okay on the server side, so did some tests with ldapsearch. It did not work at first, but I finally got it (with ldapsearch, anyway).
ldapsearch -D first.last#mydomain.local -H "ldap://hq.mydomain.local:389" -b "ou=Development,ou=Domain Users,dc=mydomain,dc=local" -W "sAMAccountName=first.last"
Maybe not the best way. For starters, the key is the -D argument, and passing sAMAccountName at the end. I'm not going to have the common name - only the windows login name, and their password. The above command will show a user his info, if the password passes.
The caveat (I think) is that ldap_sasl_bind_s() has no equivalent of setting the -D (binddn) flag. Looking at this question/answer it looks like ldap_interactive_bind_s() might, but it's a bit more involved, as I have to pass a call back.
With the example above where I set a password, but no binddn/username of any kind, who does it assume I'm trying to authenticate as?
sAMAccountName=MYDOMAIN\UserName,dc=mydomain,dc=local
This format of username is incorrect. You do not need to specify sAMAccountName in your username and don't need to specify dc unless you're using Distinguished Name. You have few options for username.
Distinguished Name
CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=Com
sAMaccountName
jsmith
The user path from a previous version of Windows
"Fabrikam\jeffsmith".
User Principal Name (UPN)
jeffsmith#Fabrikam.com
Having said that, I'm not certain if the username is the only issue you're experiencing. I have not run your code locally.
Although this answer may not directly answer your question, since I have not tested this code in Linux machine, it could give you an idea or put you in a right direction. I will not be surprised if this method is Windows specific only.
According to MSDN there're few methods you can use to authenticate a user.
The ADsOpenObject function binds to an ADSI object using explicit user name and password credentials.
This method is accepting the following parameters:
HRESULT ADsOpenObject(
_In_ LPCWSTR lpszPathName,
_In_ LPCWSTR lpszUserName,
_In_ LPCWSTR lpszPassword,
_In_ DWORD dwReserved,
_In_ REFIID riid,
_Out_ VOID **ppObject
);
Using this method you can bind to object in Active Directory by specifying username and password.
If the bind is successful, the return code is S_OK, otherwise you'll get different error messages.
I don't write programs in C++ on a daily basis. I typically work with Active Directory and Active Directory Lightweight Services in a C# world. But this sample code I wrote, shows you how to call ADsOpenObject method to bind to an ADSI object using specified credentials. In your case, just authenticate.
#include <iostream>
#include "activeds.h"
using namespace std;
int main(int argc, char* argv[])
{
HRESULT hr;
IADsContainer *pCont;
IDispatch *pDisp = NULL;
IADs *pUser;
CoInitialize(NULL);
hr = ADsOpenObject( L"LDAP://yourserver",
L"username",
L"password",
ADS_FAST_BIND, //authentication option
IID_IADs,
(void**) &pUser);
if (SUCCEEDED(hr))
{
cout << "Successfully authenticated";
}
else
cout << "Incorrect username or password";
return hr;
}
Depending on your setup, you might have to tweak ADS_AUTHENTICATION_ENUM. I suggest you install SSL Certificate and use ADS_USE_SSL binding. Dealing with passwords without SSL in AD, can be nightmare.

Chrome native host in C++, cannot communicate with Chrome

I am trying to implement a Chrome extension using runtime.connectNative and postMessage. I am following the Chrome documentation, downloaded the native messaging example, and changed the native app to using C++.
However, the native app cannot receive the message from the Chrome extension.
Meanwhile, when the native app using the printf function write message to chrome extension, the extension can not receive and the message just shown in the console.
Any ideas how to solve the problem?
You didn't provide a lot information about what you actually tried, so I will do my best to explain the steps needed to implement Chrome Extension, Native Messaging host and establish communication between them. (Please examine the following link to obtain more information about Chrome Native Messaging: Chrome Native Messaging How to.
CHROME EXTENSION
Firstly, we need to set up Chrome extension. As this will be very simple extension, we need only manifest.json file (please note this is extension's manifest file - native host will have its own manifest file as well) and background.js javascript implementation.
The following is sample manifest.json file:
{
"name": "Test extension",
"description": "Native messaging test",
"permissions": [
"nativeMessaging",
"tabs",
"activeTab",
"background",
"http://*/", "https://*/"
],
"background": {
"scripts": ["background.js"]
},
"version": "1.0",
"minimum_chrome_version": "29",
"manifest_version": 2
}
Important things here are that implementation will be provided in background.js, minimum supported Chrome version is 29 and HTTP and HTTPS are both supported.
Next, background.js file has the following content:
var port = chrome.runtime.connectNative('com.dolby.native_messaging_host');
port.onMessage.addListener(function(msg) {
console.log(msg.text);
});
port.onDisconnect.addListener(function() {
console.log("Disconnected");
});
port.postMessage({"text":"This is message from Chrome extension"});
The code itself is pretty self-explanatory - we try to connect to native host identified by com.dolby.native_messaging_host key (I will come to this in a minute). Then, we register a listener for onMessage event (this event is triggered when native host sends a message to the chrome extension). We also register a listener for disconnect event (for example when native host dies this event will be triggered). And finally, we send a message using postMessage method.
NATIVE MESSAGING HOST
Now, native host also has its own manifest.json file. Very simple manifest.json file for native host is as follows:
{
"name": "com.dolby.native_messaging_host",
"description": "Native messaging host",
"path": "C:\\Users\\dbajg\\Desktop\\Native-messaging-host\\Debug\\Native-messaging-host.exe",
"type": "stdio",
"allowed_origins": [
"chrome-extension://bjgnpdfhbcpjdfjoplajcmbleickphpg/"
]
}
Couple of interesting things here: name identifies the key under which this native host is registered. Path is full path to native host executable. Type of communication stdio means we are using standard input/output for communication (only type currently supported). And finally, allowed_origins specify which extensions can communicate with this native host - so you have to find out what is your extension's key!.
The next step is to register this Native Messaging host in registry (for Windows) and specify the location to its manifest file. The following screenshots explains how to this for Windows (examine provided link to find out how to do this in OSX and Linux):
After you've added registry entry for your native host the only remaining thing is to write your native host. The following C++ code implements simple native host that reads messages from the standard input and writes response to standard output (when you send #STOP# message the native host exits):
#include <iostream>
#include <string>
int main(){
std::string oneLine = "";
while (1){
unsigned int length = 0;
//read the first four bytes (=> Length)
/*for (int i = 0; i < 4; i++)
{
int read_char = getchar();
length += read_char * (int) pow(2.0, i*8);
std::string s = std::to_string((long long)read_char) + "\n";
fwrite(s.c_str(), sizeof(char), s.size(), f);
fflush(f);
}*/
//Neat way!
for (int i = 0; i < 4; i++)
{
unsigned int read_char = getchar();
length = length | (read_char << i*8);
}
//read the json-message
std::string msg = "";
for (int i = 0; i < length; i++)
{
msg += getchar();
}
std::string message = "{\"text\":\"This is a response message\"}";
// Collect the length of the message
unsigned int len = message.length();
// Now we can output our message
if (msg == "{\"text\":\"#STOP#\"}"){
message = "{\"text\":\"EXITING...\"}";
len = message.length();
std::cout << char(len>>0)
<< char(len>>8)
<< char(len>>16)
<< char(len>>24);
std::cout << message;
break;
}
// return stdin message
len = length;
std::cout << char(len>>0)
<< char(len>>8)
<< char(len>>16)
<< char(len>>24);
std::cout << msg << std::flush;
// return response message
// std::cout << char(len>>0)
// << char(len>>8)
// << char(len>>16)
// << char(len>>24);
//
// std::cout << message << std::flush;
}
return 0;
}
Messages sent by extension to native host is formed in a way that first byte stores the number of bytes in the message. So the first thing native host must do is to read the first 4 bytes and calculate the size of the message. I explained how to do this in another post that can be found here:
How to calculate size of the message sent by chrome extension
For future Google people, here's how I do it:
C style
Reading
char bInLen[4];
read(0, bInLen, 4); // 0 is stdin
unsigned int inLen = *(unsigned int *)bInLen;
char *inMsg = (char *)malloc(inLen);
read(0, inMsg, inLen);
inMsg[inLen] = '\0';
...
free(inMsg);
Writing
char *outMsg = "{\"text\":\"This is a response message\"}";
unsigned int outLen = strlen(outMsg);
char *bOutLen = (char *)&outLen;
write(1, bOutLen, 4); // 1 is stdout
write(1, outMsg, outLen);
fflush(stdout);
C++ style
Reading
char bInLen[4];
cin.read(bInLen, 4);
unsigned int inLen = *reinterpret_cast<unsigned int *>(bInLen);
char *inMsg = new char[inLen];
cin.read(inMsg, inLen);
string inStr(inMsg); // if you have managed types, use them!
delete[] inMsg;
Writing
string outMsg = "{\"text\":\"This is a response message\"}";
unsigned int outLen = outMsg.length();
char *bOutLen = reinterpret_cast<char *>(&outLen);
cout.write(bOutLen, 4);
cout << outMsg << flush;

Detect virtualized OS from an application?

I need to detect whether my application is running within a virtualized OS instance or not.
I've found an article with some useful information on the topic. The same article appears in multiple places, I'm unsure of the original source. VMware implements a particular invalid x86 instruction to return information about itself, while VirtualPC uses a magic number and I/O port with an IN instruction.
This is workable, but appears to be undocumented behavior in both cases. I suppose a future release of VMWare or VirtualPC might change the mechanism. Is there a better way? Is there a supported mechanism for either product?
Similarly, is there a way to detect Xen or VirtualBox?
I'm not concerned about cases where the platform is deliberately trying to hide itself. For example, honeypots use virtualization but sometimes obscure the mechanisms that malware would use to detect it. I don't care that my app would think it is not virtualized in these honeypots, I'm just looking for a "best effort" solution.
The application is mostly Java, though I'm expecting to use native code plus JNI for this particular function. Windows XP/Vista support is most important, though the mechanisms described in the referenced article are generic features of x86 and don't rely on any particular OS facility.
Have you heard about blue pill, red pill?. It's a technique used to see if you are running inside a virtual machine or not. The origin of the term stems from the matrix movie where Neo is offered a blue or a red pill (to stay inside the matrix = blue, or to enter the 'real' world = red).
The following is some code that will detect whether you are running inside 'the matrix' or not:
(code borrowed from this site which also contains some nice information about the topic at hand):
int swallow_redpill () {
unsigned char m[2+4], rpill[] = "\x0f\x01\x0d\x00\x00\x00\x00\xc3";
*((unsigned*)&rpill[3]) = (unsigned)m;
((void(*)())&rpill)();
return (m[5]>0xd0) ? 1 : 0;
}
The function will return 1 when you are running inside a virutal machine, and 0 otherwise.
Under Linux I used the command: dmidecode ( I have it both on CentOS and Ubuntu )
from the man:
dmidecode is a tool for dumping a
computer's DMI (some say SMBIOS) table
contents in a human-readable format.
So I searched the output and found out its probably Microsoft Hyper-V
Handle 0x0001, DMI type 1, 25 bytes
System Information
Manufacturer: Microsoft Corporation
Product Name: Virtual Machine
Version: 5.0
Serial Number: some-strings
UUID: some-strings
Wake-up Type: Power Switch
Handle 0x0002, DMI type 2, 8 bytes
Base Board Information
Manufacturer: Microsoft Corporation
Product Name: Virtual Machine
Version: 5.0
Serial Number: some-strings
Another way is to search to which manufacturer the MAC address of eth0 is related to: http://www.coffer.com/mac_find/
If it return Microsoft, vmware & etc.. then its probably a virtual server.
VMware has a Mechanisms to determine if software is running in a VMware virtual machine Knowledge base article which has some source code.
Microsoft also has a page on "Determining If Hypervisor Is Installed". MS spells out this requirement of a hypervisor in the IsVM TEST" section of their "Server Virtualization Validation Test" document
The VMware and MS docs both mention using the CPUID instruction to check the hypervisor-present bit (bit 31 of register ECX)
The RHEL bugtracker has one for "should set ISVM bit (ECX:31) for CPUID leaf 0x00000001" to set bit 31 of register ECX under the Xen kernel.
So without getting into vendor specifics it looks like you could use the CPUID check to know if you're running virtually or not.
No. This is impossible to detect with complete accuracy. Some virtualization systems, like QEMU, emulate an entire machine down to the hardware registers. Let's turn this around: what is it you're trying to do? Maybe we can help with that.
I think that going forward, relying on tricks like the broken SIDT virtualization is not really going to help as the hardware plugs all the holes that the weird and messy x86 architecture have left. The best would be to lobby the Vm providers for a standard way to tell that you are on a VM -- at least for the case when the user has explicitly allowed that. But if we assume that we are explicitly allowing the VM to be detected, we can just as well place visible markers in there, right? I would suggest just updating the disk on your VMs with a file telling you that you are on a VM -- a small text file in the root of the file system, for example. Or inspect the MAC of ETH0, and set that to a given known string.
On virtualbox, assuming you have control over the VM guest and you have dmidecode, you can use this command:
dmidecode -s bios-version
and it will return
VirtualBox
On linux systemd provides a command for detecting if the system is running as a virtual machine or not.
Command:
$ systemd-detect-virt
If the system is virtualized then it outputs name of the virtualization softwarwe/technology.
If not then it outputs none
For instance if the system is running KVM then:
$ systemd-detect-virt
kvm
You don't need to run it as sudo.
I'd like to recommend a paper posted on Usenix HotOS '07, Comptibility is Not Transparency: VMM Detection Myths and Realities, which concludes several techniques to tell whether the application is running in a virtualized environment.
For example, use sidt instruction as redpill does(but this instruction can also be made transparent by dynamic translation), or compare the runtime of cpuid against other non-virtualized instructions.
While installing the newes Ubuntu I discovered the package called imvirt. Have a look at it at http://micky.ibh.net/~liske/imvirt.html
This C function will detect VM Guest OS:
(Tested on Windows, compiled with Visual Studio)
#include <intrin.h>
bool isGuestOSVM()
{
unsigned int cpuInfo[4];
__cpuid((int*)cpuInfo,1);
return ((cpuInfo[2] >> 31) & 1) == 1;
}
Under Linux, you can report on /proc/cpuinfo. If it's in VMware, it usually comes-up differently than if it is on bare metal, but not always. Virtuozzo shows a pass-through to the underlying hardware.
Try by reading the SMBIOS structures, especially the structs with the BIOS information.
In Linux you can use the dmidecode utility to browse the information.
Check the tool virt-what. It uses previously mentioned dmidecode to determine if you are on a virtualized host and the type.
I Tried A Different approach suggested by my friend.Virtual Machines run on VMWARE doesnt have CPU TEMPERATURE property. i.e They Dont Show The Temperature of the CPU. I am using CPU Thermometer Application For Checking The CPU Temperature.
(Windows Running In VMWARE)
(Windows Running On A Real CPU)
So I Code a Small C Programme to detect the temperature Senser
#include "stdafx.h"
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
int main(int argc, char **argv)
{
HRESULT hres;
// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
cout << "Failed to initialize COM library. Error code = 0x"
<< hex << hres << endl;
return 1; // Program has failed.
}
// Step 2: --------------------------------------------------
// Set general COM security levels --------------------------
hres = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (FAILED(hres))
{
cout << "Failed to initialize security. Error code = 0x"
<< hex << hres << endl;
CoUninitialize();
return 1; // Program has failed.
}
// Step 3: ---------------------------------------------------
// Obtain the initial locator to WMI -------------------------
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *)&pLoc);
if (FAILED(hres))
{
cout << "Failed to create IWbemLocator object."
<< " Err code = 0x"
<< hex << hres << endl;
CoUninitialize();
return 1; // Program has failed.
}
// Step 4: -----------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
// Connect to the root\cimv2 namespace with
// the current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (for example, Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x"
<< hex << hres << endl;
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;
// Step 5: --------------------------------------------------
// Set security levels on the proxy -------------------------
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
// Step 6: --------------------------------------------------
// Use the IWbemServices pointer to make requests of WMI ----
// For example, get the name of the operating system
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t(L"SELECT * FROM Win32_TemperatureProbe"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if (FAILED(hres))
{
cout << "Query for operating system name failed."
<< " Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
// Step 7: -------------------------------------------------
// Get the data from the query in step 6 -------------------
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if (0 == uReturn)
{
break;
}
VARIANT vtProp;
// Get the value of the Name property
hr = pclsObj->Get(L"SystemName", 0, &vtProp, 0, 0);
wcout << " OS Name : " << vtProp.bstrVal << endl;
VariantClear(&vtProp);
VARIANT vtProp1;
VariantInit(&vtProp1);
pclsObj->Get(L"Caption", 0, &vtProp1, 0, 0);
wcout << "Caption: " << vtProp1.bstrVal << endl;
VariantClear(&vtProp1);
pclsObj->Release();
}
// Cleanup
// ========
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();
return 0; // Program successfully completed.
}
Output On a Vmware Machine
Output On A Real Cpu
I use this C# class to detect if the Guest OS is running inside a virtual environment (windows only):
sysInfo.cs
using System;
using System.Management;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
public class sysInfo
{
public static Boolean isVM()
{
bool foundMatch = false;
ManagementObjectSearcher search1 = new ManagementObjectSearcher("select * from Win32_BIOS");
var enu = search1.Get().GetEnumerator();
if (!enu.MoveNext()) throw new Exception("Unexpected WMI query failure");
string biosVersion = enu.Current["version"].ToString();
string biosSerialNumber = enu.Current["SerialNumber"].ToString();
try
{
foundMatch = Regex.IsMatch(biosVersion + " " + biosSerialNumber, "VMware|VIRTUAL|A M I|Xen", RegexOptions.IgnoreCase);
}
catch (ArgumentException ex)
{
// Syntax error in the regular expression
}
ManagementObjectSearcher search2 = new ManagementObjectSearcher("select * from Win32_ComputerSystem");
var enu2 = search2.Get().GetEnumerator();
if (!enu2.MoveNext()) throw new Exception("Unexpected WMI query failure");
string manufacturer = enu2.Current["manufacturer"].ToString();
string model = enu2.Current["model"].ToString();
try
{
foundMatch = Regex.IsMatch(manufacturer + " " + model, "Microsoft|VMWare|Virtual", RegexOptions.IgnoreCase);
}
catch (ArgumentException ex)
{
// Syntax error in the regular expression
}
return foundMatch;
}
}
}
Usage:
if (sysInfo.isVM()) {
Console.WriteLine("VM FOUND");
}
I came up with universal way to detect every type of windows virtual machine with just 1 line of code. It supports win7--10 (xp not tested yet).
Why we need universal way ?
Most common used way is to search and match vendor values from win32. But what if there are 1000+ VM manufacturers ? then you would have to write a code to match 1000+ VM signatures. But its time waste. Even after sometime, there would be new other VMs launched and your script would be wasted.
Background
I worked on it for many months. I done many tests upon which I observed that:
win32_portconnector always null and empty on VMs. Please see full report
//asked at: https://stackoverflow.com/q/64846900/14919621
what win32_portconnector is used for ? This question have 3 parts.
1) What is the use case of win32_portconnector ? //https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-portconnector
2) Can I get state of ports using it like Mouse cable, charger, HDMI cables etc ?
3) Why VM have null results on this query : Get-WmiObject Win32_PortConnector ?
On VM:
PS C:\Users\Administrator> Get-WmiObject Win32_PortConnector
On Real environment:
PS C:\Users\Administrator> Get-WmiObject Win32_PortConnector
Tag : Port Connector 0
ConnectorType : {23, 3}
SerialNumber :
ExternalReferenceDesignator :
PortType : 2
Tag : Port Connector 1
ConnectorType : {21, 2}
SerialNumber :
ExternalReferenceDesignator :
PortType : 9
Tag : Port Connector 2
ConnectorType : {64}
SerialNumber :
ExternalReferenceDesignator :
PortType : 16
Tag : Port Connector 3
ConnectorType : {22, 3}
SerialNumber :
ExternalReferenceDesignator :
PortType : 28
Tag : Port Connector 4
ConnectorType : {54}
SerialNumber :
ExternalReferenceDesignator :
PortType : 17
Tag : Port Connector 5
ConnectorType : {38}
SerialNumber :
ExternalReferenceDesignator :
PortType : 30
Tag : Port Connector 6
ConnectorType : {39}
SerialNumber :
ExternalReferenceDesignator :
PortType : 31
Show me Code
Based upon these tests, I have made an tiny program which can detect windows VMs.
//#graysuit
//https://graysuit.github.io
//https://github.com/Back-X/anti-vm
using System;
using System.Windows.Forms;
public class Universal_VM_Detector
{
static void Main()
{
if((new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_PortConnector")).Get().Count == 0)
{
MessageBox.Show("VM detected !");
}
else
{
MessageBox.Show("VM NOT detected !");
}
}
}
You can read code or get compiled executable.
Stability
It is tested on many environments and is very stable.
Detects Visrtualbox
Detects Vmware
Detects Windows Server
Detects RDP
Detects Virustotal
Detects any.run
etc...