Continuing from the previous article, the first step in determining a possible way to kick the V740 back into EVDO mode is to understand how the Verizon connection manager software interfaces with it. In order to do this, I used WinDbg and IDA for debugging and code analysis, respectively.
The software that Verizon ships presents a, uninform user interface regardless of what type of device you might be using. This means that it likely has some sort of generic abstraction layer to communicate with any connected devices (as the connection manager software supports a wide variety of cards and tethered phones, from many different manufacturers).
Indeed, it turns out that there is an abstraction layer, in the term of a set of DLLs present in the connection manager installation directory, which are named based off of the device they support (e.g. WMCLGE_VX8700.dll, WMC_NOK_6215i.dll, WmcV740.dll). These DLLs implement a high level interface in the form of a (fairly simple) exported C API, which is then used by the connection manager software to control the connected device.
The abstraction layer is fairly generic across devices, and as such does not support a whole lot of advanced device-specific features. However, it does provide support for operations like querying information about the network and over the air protocols in use, link quality (e.g. signal levels), sending and receiving SMS messages, manipulating the phone book (for some devices, not the V740 as it would have it), powering on and off the device, performing over the air activation, and a handful of other operations. In turn, each device-specific module translates requests from the standard exported C API into calls to their associated devices, using whatever device-specific mechanism that device offers for communication with the computer. This is typically done by building a sort of adapter from the connection manager’s expected C API interface to a vendor-specific library or SDK for communicating with each device.
As most of the potentially APIs in question have only one or two parameters (and could be easily inspected on the fly by debugging the connection manager) it was fairly trivial to gain a basic working understanding of the device abstraction layer API. The approach that I took to accomplish this was to simply set a breakpoint on all of the exported functions (in WinDbg, bm wmcv740!*), and from there, record which functions were invoked by what parts of the connection manager GUI and inspect in/out parameter values, in conjunction with analysis in IDA. Although there are some fairly tantalyzingly named functions (e.g. WMC_SetPower, WMC_SetRadioPower), none of the APIs in question turned out to do just what I wanted. (The calls to set low power mode / normal mode / on / off for the device cause any active PPP dialup connection over the device to be reset, thereby ruling them out as useful for my purposees.)
The fact that none of the APIs did what I set out to look for (though I did determine how to do some interesting things like determine signal strengths and what sort of coverage is present) is not all that surprising, as there doesn’t appear to be any sort of support for forcing a device to change protocols on-the-fly in the connection manager app (or support for forcing a dormant mode transition). Because the abstraction layer essentially implements only the minimum amount of functionality for the connection manager software to function, extra device-specific functionality that isn’t used by the connection manager isn’t directly supported by the standard exported C API. All of this essentially translates into there being no dice on using the exported APIs to do what I wanted with forcing the card to upgrade back to EVDO on-the-fly.
While this might initially seem like a pretty fatal roadblock (at least as far as using the connection manager and its libraries to perform the task at hand), it turned out that there was actually something of value in the V740 module after all, even if it didn’t directly expose any useful functionality of this sort through the exported interface. In a stroke of luck, it just so happened that the V740 module was linked to what appeared to be a debug version of the Novatel SDK. In particular, two important points arose from this being the case:
First, the debug version of the Novatel SDK would appear to have handy debug prints all over the place, many naming the function they are called from, providing a fair amount of insight into what internal functions in the module are named. Essentially, the debug prints made it essentially the same as if public symbols had been made available for the Novatel SDK part of the module, as most non-trivial functions in the SDK appear to contain at least one debug print, and virtually all the debug prints named the function they were called from.
Second, the SDK itself and the abstraction layer module appear to have been built without a certain type of linker optimization (/OPT:REF) that removes unreferenced code and data from a final binary. (Disabling this optimization is a default setting for debug builds.) This meant that for the most part, a large part of the Novatel SDK (with debug prints included) happened to be present in the V740 abstraction layer module. As a result of this, there existed the possibility that there might be something of use still there inside the V740 module, even if it wasn’t directly exposed.
At this point, I decided to continue down the road of examining the abstraction layer module, in the hopes that some portion of the baked-in Novatel SDK might be of use.
Next time: Taking a closer look at the V740 abstraction layer module and the Novatel SDK embedded into it.
[…] Nynaeve Adventures in Windows debugging and reverse engineering. « Reversing the V740, part 2: Digging deeper: The connection manager software […]