Thursday, December 02, 2010

Getting elapsed time since last Windows wakeup via CallNtPowerInformation

Windows provides the last system wake time via CallNtPowerInformation. It returns the "interrupt-time count, in 100-nanosecond units". To obtain the time since last wake, this needs to be subtracted from another value, but the documentation doesn't explain what other value can be used. In Windows 7, GetTickCount and GetTickCount64 (which return time in milliseconds) work great. The combination even returns a good result after a bootup, when the system hasn't slept yet. Do not use QueryUnbiasedInterruptTime or QueryPerformanceCounter. The latter will be close enough at first, but every time the system sleeps and wakes, additional error will accumulate.

Wednesday, November 10, 2010

Using Detours Express from GCC

Detours Express must be compiled using a Microsoft C++ compiler. It can be used from GCC, but some significant issues do come up.

When attempting to use Detours from GCC, the first problem is that GNU ld cannot resolve some symbols in static libraries that were created by Microsoft compilers. This can be solved by creating a DLL. First, a .def Module Definition File needs to be created to export the needed symbols. The list of functions can easily be obtained from the header file, using sed -n "s/^.* WINAPI \([^(]*\)(.*$/\1/p" detours.h. Once you have that, you just have to add a single data export and the statements that go at the beginning of the .def file:

..\detoured.lib msvcrt.lib kernel32.lib /out:detours.dll
LIBRARY detours
EXPORTS
DETOUR_EXE_RESTORE_GUID DATA


If you want, you can create a resource file with VERSIONINFO. Simply copy detours.rc in the Detours source directory and then edit it. The only fields that need to be edited are the FileDescription and DLL names. It's probably also a good idea to set the VS_FF_PRIVATEBUILD flag in FILEFLAGS by setting FILEFLAGS to 0x8L, and below provide a "PrivateBuild" VALUE with information about your build.

If you want to name your DLL detours.dll, it must not be built in the lib directory, because that would overwrite detours.lib, which is your input file. So, go to another directory and create the DLL:

set LIB=C:\WinDDK\7600.16385.1\lib\wxp\i386;C:\WinDDK\7600.16385.1\lib\Crt\i386
link /release /machine:x86 /dll /def:detours.def /incremental:no /subsystem:console detours.res ..\detours.lib ..\detoured.lib msvcrt.lib kernel32.lib /out:detours.dll


At this point, you have a usable DLL, but it's a good idea to create a corresponding .dll.a interface library file for GCC. This is a simple process, but a stdcall function decoration issue needs to be dealt with. The Detours Express API uses the stdcall calling convention, but the functions in the DLL have no decoration. (Windows system DLLs like kernel32.dll do the same thing.) It can be a problem, because GCC will attempt to link stdcall functions to decorated names such as DetourAttach@8. To solve this, create an entirely new .def file using gendef. Use the the -a switch, because gendef can't detect that zero-argument functions use stdcall, and do it in a new directory if you want to keep the old detours.def. DetourGetDetouredMarker forwards to Detoured in detoured.dll, so either run gendef on detoured.dll first or add the @0 to that name manually. Use dlltool to create the interface library, using the -k switch so the decorated names in the interface library can dynamically link with the undecorated exports in detours.dll:

dlltool -k -d detours.def -D detours.dll -l libdetours.a

Finally, everything is ready for compilation. The sample programs provide a simple way to test Detours Express, and with some minor changes, they can be compiled with g++. The main issue is that g++ follows the standard and refuses to automatically convert function pointers to void pointers, but that's easy to fix by adding (PVOID) casts.

Unfortunately, when using GNU ld from binutils 2.20.51.20100410, functions which are imported from DLLs are intercepted in the current module, bit not in any other modules. For example, the simple sample outputs that it "slept 0 ticks". This is because the thunk (which is an indirect jump to the actual function) is intercepted instead of the actual function. Detours attempts to correct this via DetourCodeFromPointer, but it fails because GNU ld doesn't fill out the data directory structure for the import address table and detour_is_imported returns false. (You can use objdump -p to view the data directory.) This bug was fixed in September 2010, and the binutils-2.21.51.tar.bz2 snapshot contains the fix. (Here is a thread discussing the fix and one CVS log entry from the fix.)

If you're using a buggy ld, it's also possible to work around this problem by declaring imported functions with __declspec(dllimport). When using the MinGW headers, Windows API functions may be declared this way by defining __W32API_USE_DLLIMPORT__ before including header files. This causes the corresponding function addresses to be correct, but no longer constant (due to dynamic linking). When compiling via g++, this is not a problem because the compiler automatically generates code to initialize global variables. However, gcc cannot do this and so code must be added to initialize such global variables at runtime.

Building Detours with the WDK compiler

Detours is a library for intercepting arbitrary Win32 binary functions. A free version called Detours Express is available "for research, non-commercial, and non-production use on 32-bit code".

The Detours Express package only contains source code. It must be compiled using Microsoft's C++ compiler because it uses non-standard extensions such as the try-except statement. I compiled it using the compiler in the WDK (Windows Driver Kit). (To install, download the WDK CD image and install "Build Environments". That list of packages requires 1.37 GB. If you want to reduce this, you can uninstall individual unwanted packages by right-clicking on their .msi files and selecting uninstall.)

Detours Express uses the DbgHelp library, but dbghelp.h is not in the WDK. This may be remedied by downloading Debugging Tools for Windows and installing the included SDK. (Detours Express loads dbghelp.dll via LoadLibraryA, so you don't have to worry about linking that in.)

By default, the compiler isn't in the path and there is no search path for include files or libraries. This may be remedied by setting some environment variables from a batch file:

PATH=C:\WinDDK\7600.16385.1\bin\x86;C:\WinDDK\7600.16385.1\bin\x86\x86;%PATH%
SET "INCLUDE=c:\WinDDK\7600.16385.1\inc\api;c:\WinDDK\7600.16385.1\inc\crt;C:\Program Files\Debugging Tools for Windows (x86)\sdk\inc"
SET LIB=C:\WinDDK\7600.16385.1\lib\wxp\i386


Recent versions of the WDK do not include lib.exe. This is not a problem, because lib simply called link. Simply replace lib with link /lib in the Makefile. After that, just run nmake and Detours will build.

Saturday, October 30, 2010

Yahoo Messenger also censors messages

I already knew that Windows Live Messenger censors messages at the server. I thought Yahoo Messenger was better. It is not; it does the same thing and it doesn't even notify when message delivery fails. This is happening with messages sent between Trillian and Miranda IM, so it has to be sever-side.

The best solution is encryption. I recommend Off-the-Record Messaging (OTR).

Wednesday, October 20, 2010

Getting rid of my last name in Windows Live Messenger 2011

Windows Live Messenger 2011 tries to force people to use their real first and last name as their display name. There is no more display name option in Messenger, and the only way to change the name is via Windows Live profile settings on the web, where the web page requires a that both a first and last name is input. I went to a page showing unicode spaces and tried pasting those as my last name. Most resulted in an error, but one finally worked. I think it was U+202F narrow no-break space. It seems I don't have a space as my last name; the last name is gone.

Saturday, October 02, 2010

Virtual TI 2.5 Windows 7 compatibility fix

If you run Virtual TI 2.5 beta 5 under Windows 7, it fails with an error dialog which says "Failed to set data for 'LastEmuVersion'". A simple workaround is always running Virtual TI as Administrator, but that gets annoying.

The error means that Virtual TI was unable to save settings in the registry. It attempts to save settings under HKEY_LOCAL_MACHINE\SOFTWARE\ACZ, and it is not allowed to write there. Instead, it should be saving them under HKEY_CURRENT_USER\Software\ACZ. Normally, Windows 7 registry virtualization would automatically fix this problem by redirecting writes HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\ACZ, but something goes wrong.

To fix the problem, open regedit and grant yourself write access to KEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\ACZ and all of its child objects. If the key doesn't exist, create it.

Wednesday, September 29, 2010

A quick summary of some TI-85 emulators

I tried a few TI-85 emulators, hoping that they would be more convenient than testing code on a real calculator. Here are some observations using my version 9 TI-85 ROM:
  • Wabbitemu has a nice user interface. The TI-86 skin looks great, and it's nice how I get visual feedback when I press buttons. I don't mind that it's not a TI-85 skin. However, there doesn't seem to be any way to transfer TI-85 files to the emulator, so it's useless for development.
  • TilEm 0.972 looks kind of ugly due to the scaled up low resolution skin, and the screen standing out too much. Multiple attempts to transfer a backup to the calculator failed, and so I couldn't use it for running assembler programs. I couldn't get 0.973 to display the skin.
  • Virtual TI 2.5 has some problems, but it is usable. In Windows 7, it has to be run as Administrator (or else I get a "Failed to set data for 'LastEmuVersion'" error). I've had some linking failures, but I was generally able to transfer a backup after resetting the calculator. When transferring variables, I got annoying linking errors whenever a variable under that name exist, so I'm forced to delete variables before re-uploading them. The skin looks worse than Wabbitemu, but it is a TI-85 skin which looks like my TI-85, and it looks a lot better than TilEm.

Sunday, September 26, 2010

Usgard relocation table format

Usgard is the most recent and most capable assembly shell for the TI-85 graphing calculator. It can run ZShell programs, but it also offers additional functionality which can be used when writing programs specifically for Usgard. The primary advantages are relocation and functions for accessing TI-85 variables.

On the TI-85, assembler programs are stored in string variables, and they execute in-place. The initial location of the variable depends on the amount of free RAM, and the variable can me moved when other variables are deleted. Because of this ZShell code cannot rely on being at a fixed address. Usgard's relocation almost removes this concern. At the end of a program is a list which shows what locations in the code need to be updated with the current position. The list contains two kinds of entries:
  • a single byte, whose value is the offset of the current relocation position minus the offset of the previous relocation position.
  • a zero byte, followed by a 16 bit little endian absolute offset of the relocation position.
The single byte form is used whenever possible. At the beginning, the previous relocation position is considered to be zero, and the single byte form can be used for relocations at absolute offsets 1 through 255. The file is assembled starting at offset zero (".org 0") and this determines absolute offsets and initial values of locations requiring relocation. All locations requiring relocation contain little endian 16 bit numbers. The list of relocations is followed by a four byte header which consists of two 16 bit little endian values. The first value is zero minus the number of bytes in the relocation table, and the second value is the number of relocation entries.

To perform relocation, Usgard needs to add the current offset of the program to all of the locations requiring relocation. When the program terminates, Usgard undoes these changes by subtracting the current offset from the locations.

The only disadvantage of Usgard relocation is that the relocation table is created via a sort of kludge using an ancient toolchain which runs in MS-DOS. All operands which require relocation need to be prefixed with an ampersand. Before assembly, the code is preprocessed via SRCWIZ.EXE, which removes the ampersands and adds labels of R_ followed by a number, with the number starting at zero. Then, this code is assembled, and STRING85.EXE creates the relocation table based on the listing produced by the assembler. A batch file ties all this together and at the end replaces the files altered by SRCWIZ with the originals.

Several programs in the Usgard directory were compiled with old Borland Pascal compilers. They fail with "Runtime error 200", meaning divide by zero, because modern computers are too fast for Borland Pascal delay loop calibration. Fortunately, this is easy to fix with TPPATCH.

Overall, the toolchain works, but I would prefer something more modern. Maybe I'll try using the GNU assembler or even the Small Device C Compiler (SDCC).