You don't really need the source code. If you had it, you could do *all* sorts of things ... but even without, plenty is possible.
In fact, the term "wrapper" implies that you don't have the source code; you're working without it. Generally speaking, a 'wrapper' pretends to be some sort of library ... say DirectX ... but instead of actually doing whatever the application tells it to, it translates those requests into something else ... say OpenGL instructions.
If you're writing a replacement for a DLL, all you do is write a DLL of your own that contains functions with identical names to those in the DLL you're replacing. Then when the app calls your functions ... you do something. Maybe emulate what it's asking for yourself. (A wrapper layer isn't much different from an emulation layer). That way you can make something run when the hardware/whatever it's looking for isn't present - you mimic its capabilities.
However, it's not necessarily easy. In the case of graphics engines, in particular: OpenGL and Direct3D are both pretty complex, so simply writing something that translated the calls would be time consuming, and DirectX in general is unusual in that it doesn't use simple libraries; it uses COM.
Still possible ... but hard. The FF8 Configurator could be one example of a wrapper; it 'wraps' DirectMusic, so all of FF8's requests to DirectMusic actually get sent to our program instead. In this case, the app actually passes them straight on to DirectMusic - but it means we get notified about everything music related FF8 does, so we can, for example, load soundfonts in, change the name of the file it's looking for, and so on.