sábado, 26 de septiembre de 2015

Error "BUG" en Microsoft-Edge (TRK:0285936)

Microsoft TRK:0285936
Microsoft Case: 31110

Recientemente he notificado a Microsoft un "error" que he localizado en su nuevo navegador Microsoft-Edge. Se trata de un fallo en el parser del campo dedicado a la dirección o URL, el cual encontramos en la parte superior de la ventana del navegador.


Aunque Microsoft no lo considera una vulnerabilidad desde el punto de vista de la seguridad del sistema, si que están de acuerdo conmigo en que puede ser utilizado para realizar un ataque de Denegación de Servicio (DoS).


En fallo hace que Microsoft-Edge entre en una especie de bucle infinito que se dedica a abrir de manera continuada gran cantidad de nuevas pestañas vacías en el navegador. Esto, no solamente provoca una Denegación de Servicio sobre el equipo atacado, dado que impide que el usuario pueda navegar por internet, sino que además puede llegar a provocar una sobrecarga de la memoria (Heap exhaustion), ya que por cada nueva pestaña que se abre, se consume una cantidad de memoria que no es liberada.


Cronología de comunicaciones entre mi persona y el equipo de seguridad de Microsoft:
  • El primer contacto con el equipo de seguridad de Microsoft lo realicé el día (03/09/2015) remitiéndoles un correo electrónico para notificar dicho hallazgo para que sus expertos lo analizaran en profundidad.
  • El equipo me responde el mismo día (03/09/2015 diciéndome que no se puede explotar remotamente y que por lo tanto no lo tendrán en consideración, ya que, entienden que es necesario tener acceso físico al equipo para poder explotar este fallo.
  • Ese mismo día (03/09/2015) les envío otro e-mail con una pequeña prueba de concepto para que vean que si puede ser explotado remotamente y además desde varios frentes distintos.
  • El mismo día (03/09/2015) me notifican que lo van a trasladar al equipo de análisis para su investigación.
  • El día (05/09/2015) me agradecen nuevamente la información facilitada y me indican que van a abrir un nuevo caso (nº 31110) y que el administrador de casos (Michael) se pondrá en contacto conmigo en cuanto tenga más información al respecto. Me piden que por favor, en un principio respete las "Directrices de divulgación de vulnerabilidades coordinada" y que no revele públicamente este hallazgo para permitir que los usuarios tengan la posibilidad de actualizar sus sistemas y estar protegidos ante eventuales ataques.
  • Así lo hago, y no revelo nada para evitar que "el lado oscuro" pueda hacer un mal uso de este fallo en Microsoft-Edge.
  • Finalmente, el día (18/09/2015) me contestan con el siguiente e-mail:
"After our investigation we have determined this to be user-recoverable temporary DoS. This does not meet the bar for security servicing and we will be closing out as wont fix."


Básicamente que se trata de una "Denegación de Servicio" y que no lo consideran un problema para la seguridad y que por tanto no se aplicará una solución al respecto.


NOTA: A día de hoy 26 de Noviembre de 2015, Microsoft ya ha aplicado un parche que repara este Bug. "De nada Microsoft, un saludo".


¡ADVERTENCIA! A continuación podéis probar el fallo encontrado en vuestro navegador (Microsoft-Edge) bajo vuestra responsabilidad, yo no me hago responsable de los daños que se puedan ocasionar en vuestros equipos. Para poder probar este "Bug" en vuestros navegador podéis pulsar sobre este LINK desde Microsoft-Edge y veréis el efecto de infinitas pestañas abriéndose y consumiendo la memoria de vuestro sistema.

Así que, ya sabéis, si estáis utilizando Microsoft-Edge que sepáis que existen una serie de "bugs" que pueden provocar una Denegación de Servicio en vuestro acceso a internet e incluso consumir la totalidad de la memoria de vuestros sistemas, eso sí, de momento no parece que vaya a haber una solución al respecto.


Ya veremos si en futuras actualizaciones corrigen estos problemas o por el contrario será el clásico "bug" que se arrastra durante años, espero que no.


NOTA: A día de hoy 26 de Noviembre de 2015, Microsoft ya ha aplicado un parche que repara este Bug. "De nada Microsoft, un saludo".

miércoles, 16 de septiembre de 2015

MIDLRT - Generate metadata files (.winmd)

If you are programming a custom Windows Runtime component by hand, one of things you must to do is generate the IDL (Interface Definition Language) file. Once you have that file, you can get the metadata file (.winmd) by using the "MIDLRT" tool.


MIDLRT is a command line tool used to create metadata (.winmd) files that represent the API of your own custom Windows Runtime component.


You can use this nice tool as easy as writing this command:


C:>midlrt filename.idl


One option you can specify is the "metadata_dir" option, like in this example:


C:>midlrt MyRuntimeComponent.idl /metadata_dir "C:\windows\system32\WinMetaData"


When the tool MIDLRT has finished his job, you will have the following files in your current directory:


  • dlldata.c
  • MyRuntimeComponent.h
  • MyRuntimeComponent.winmd
  • MyRuntimeComponent_i.c
  • MyRuntimeComponent_p.c


Another nice tool you can use with all this stuff is "WINMDIDL". This is also a command-line tool you can use to generate automatically IDL files from your metadata files (.winmd) like this:


C:>winmdidl MyRuntimeComponent.winmd

martes, 15 de septiembre de 2015

C++/CX & Xaml Data Binding

There is a few methods that you can use to make a C++/CX class with data-bindable capability. The most simple way is by adding an attribute to the class declaration:


[Windows::UI::Xaml::Data:Bindable]

public ref class SampleDataClass sealed
{
...
};


But, What about non-public classes? With the non-public classes you can declare the class by implementing either the ICustomPropertyProvider interface or IMap:


ref class SampleDataNonPublicClass sealed : Windows::UI::Xaml::Data::ICustomPropertyProvider
{
...
public:
virtual Windows::UI::Xaml::Data::ICustomProperty^ GetCustomProperty(Platform::String^ name);
virtual Windows::UI::Xaml::Data::ICustomProperty^ GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::Type type)
property Windows::UI::Xaml::Interop::TypeName Type
{
virtual Windows::UI::Xaml::Interop::TypeName get() { return this->GetType(); }


}

virtual Platform::String^ GetStringRepresentation()
{return this->ToString();
} };

jueves, 3 de septiembre de 2015

Windows Runtime DateTime to SYSTEMTIME conversion

This post is about how to make date/time conversion between Windows::Foundation::DateTime and SYSTEMTIME structure types. Let's go to see by example:


// First we obtain the current DateTime from Calendar class

Windows::Globalization::Calendar^ cal = ref new Windows::Globalization::Calendar();
Windows::Foundation::DateTime date= cal->GetDateTime();


// Here, we are converting DateTime to a 64bit value (UniversalTime format)
ULARGE_INTEGER time;
time.QuadPart = date.UniversalTime;


// Now convert the ULARGE_INTEGER to a FILETIME structure
FILETIME fileTime;
fileTime.dwHighDateTime = time.HighPart;
fileTime.dwLowDateTime = time.LowPart;


// And finally we get a SYSTEMTIME value by calling the FileTimeToSystemTime Windows Api.
SYSTEMTIME systemTime;
FileTimeToSystemTime(&fileTime, &systemTime);

With C++ and once again, we are doing many things to something simple but sometimes necessary.

C++ Platform::String^ object to const wchar_t* conversion

In Windows Store applications, for example when you want to make a shared library, it is necessary to make use of common types like Platform::String. All the public types must be types from Windows Runtime to make it possible a cross language usage of your libraries (C++, JavaScript, C#, VB).

But when you want to use the C++ standard types like wchar_t or std::wstring, you're going to need a temporary conversion from Windows Runtime types to C++ Standard types.

You can access the string value of a Platform::String^ object by using the Data() method like this:

Platform::String^ ps3DModel(L"Gear");
std::wstring _3DModel = ps3DModel->Data();


Now, you can use the _3DModel std::wstring like another C++ standard string by using his own methods. Also, you could have converted to a "const wchar_t type":


const wchar_t * _3DModel = ps3DModel->Data();

The problem is when you want to make any changes into the ps3DModel Platform::String object since this is inmutable. What you mus to do is make a copy of the string into a std::wstring object and them modify it according to your needs. Later, when you must save the changes into the Platform::String object, you must create as a new "ref new Platform::String^". But better, let's see this with a small example:


// We create the Platform::String object
Platform::String^ ps3DModel(L"Gear");

// Now, we copy the string into a new wstring object
std::wstring _3DModel = ps3DModel->Data();

// Here we make some changes
_3DModel = L"_GEAR_";

// An finally, we put the changes into the original 'ps3DModel' object
ps3DModel = ref new Platform::String(_3DModel.c_str());

WinRT with C++ Standard vs C++/CX

OFFTOPIC:
Nota: Hoy he decidido escribir esta publicación del blog en inglés.
Note: Today I decided to write this blog post in English.


In a new application than I am developing for a company, I had to decide if to make use of C++/CX (C++ with Component Extension) or make all the main stuff in C++ standard and ABI/COM.

All of you than have had to work with COM (Component Object Model) and fighting with the interfaces, reference count, etc. known the tricky and heavy that it can become.

As an example of the easy approach using C++/CX, I am creating a new Uri object, like this:

auto uriEasyWay = ref new Windows::Foundation::Uri(http://www.manuelvillasur.com);
assert(wcscmp(uriEasyWay->AbsoluteUri->Data(), L"http://www.manuelvillasur.com/") == 0);


Now, I going to show you the more difficult approach using C++ Standard and  ABI/COM interfaces:

HSTRING_HEADER header = {};
HSTRING string = nullptr;

HRESULT hr = WindowsCreateStringReference(L"Windows.Foundation.Uri", 22, &header, &string);

if (SUCCEEDED(hr)) {
    ABI::Windows::Foundation::IUriRuntimeClassFactory * factory = nullptr;
    hr = RoGetActivationFactory(string, __uuidof(factory), reinterpret_cast<void **>(&factory));

    if (SUCCEEDED(hr)) {
        HSTRING stringUri = nullptr;
        hr = WindowsCreateStringReference(L"http://www.manuelvillasur.com", 24, &header, &stringUri);

        if (SUCCEEDED(hr)) {
            ABI::Windows::Foundation::IUriRuntimeClass * uri = nullptr;
            hr = factory->CreateUri(stringUri, &uri);

            if (SUCCEEDED(hr)) {
                HSTRING absUriString = nullptr;
                hr = uri->get_AbsoluteUri(&absUriString);
                if (SUCCEEDED(hr)) {
                    const WCHAR * uriString = WindowsGetStringRawBuffer(absUriString, nullptr);
                    assert(wcscmp(uriString, L"http://www.manuelvillasur.com/") == 0);
                    WindowsDeleteString(absUriString);
                }
                uri->Release();
            }
        }
        factory->Release();
    }
}

martes, 1 de septiembre de 2015

C++ Moderno

Si eres programador de C++, no te quedes atrás y ponte las pilas con C++ Moderno, porque ya viene pisando fuerte desde hace unos añitos y cada vez se está haciendo notar más.


Con las nuevas especificaciones del lenguaje de programación C++ (C++11, C++14, 17 ...) vienen, como es lógico, nuevas características interesantes y poderosas que no podemos dejar de utilizar por desconocimiento. Así, aunque podemos seguir programando en C++ "antiguo", hacer caso omiso de las nuevas características del lenguaje impedirá, entre otras cosas, que seas más productivo.


Como ejemplo, puedes echar un vistazo a esta función que localicé hace tiempo por Github (https://gist.github.com/goldshtn/7433212) en la cual puedes ver algunas de estas nuevas características del lenguaje:


#include <iostream>

#include <future>


using namespace std;


template <typename Fn, typename... Args>

auto do_async_with_log(ostream& os, Fn&& fn, Args&&... args) ->

         future

{

    os << "[TID=" << this_thread::get_id()

       << "] Starting to invoke function..." << endl;

    auto bound = bind(fn, forward(args...));

    return async([b=move(bound),&os]() mutable {

            auto result = b();

            os << "[TID=" << this_thread::get_id()

               << "] ...invocation done, returning " << result << endl;

             return result;

     });

}


Cualquier programador de C++ de "la vieja escuela", posiblemente al observar este código se pregunte ¿Esto es C++? Pues sí, pero esto es C++ Moderno.


Algunas de las nuevas características que debieras ir mirando son:


  • Plantillas Variádicas,
  • Bucles For basados en rango,
  • Inicializadores de listas,
  • Expresiones Lambdas,
  • Concurrencia,
  • Especificadores como Override, Final, noexcept, decltype, ...
  • Punteros inteligentes,
  • Referencias Rvalue y semántica move,
  • etc.