How to install packages from sid in Debian 6 Squeeze

Sometimes you need to install specific package from sid in Debian. There might be different reasons for this, for example, you need to install gcc-4.5 and g++-4.5 because you need to compile special software and it requires some extra gcc features.

At the current moment, gcc-4.5 is not included in stable release of Debian 6, so I guess it might be a good example to start from. First, you need to locate sid repository for the package and for that you can use Debian package search: debian qa page

Now, by entering there gcc-4.5 and pressing “Go” button you will find out page for unstable repository: http://packages.debian.org/source/unstable/gcc-4.5. Click on any of subitems of package and pickup it’s architecture, for example, amd64. Here is the page we got: http://packages.debian.org/sid/amd64/g++-4.5/download

As you can see on the last page, it says that you can use the following mirror to get this package from sid:

deb http://ftp.de.debian.org/debian sid main

Edit your file /etc/apt/sources.list and add the mirror above. Close editor and save changes and update your apt database:

sudo apt-get update

Now you can install gcc-4.5 and g++-4.5 using the following command:

sudo apt-get install gcc-4.5 g++-4.5

After everything is installed, edit again your /etc/apt/sources.list and comment-out or remove “deb http://ftp.de.debian.org/debian sid main” and update your apt:

sudo apt-get update

You’re done.

Trying 3.0.0-rc7+ vanilla kernel in Debian 6 Squeeze 64-bit and VirtualBox issues

I’ve decided to try the vanilla kernel from kernel.org, and I’ve noticed that the VirtualBox vboxdrv driver did not compile after I installed the new kernel. Here is my kernel:

volodymyr@sv1:~$ uname -a
Linux sv1 3.0.0-rc7+ #3 SMP Tue Jul 12 19:47:41 CEST 2011 x86_64 GNU/Linux

Well, I guess the easiest way to solve virtualbox problem is to try to reinstall virtualbox-ose-dkms package in this way:

sudo apt-get –reinstall install virtualbox-ose-dkms

But it fails for me:

volodymyr@sv1:/var/lib/dkms$ sudo apt-get –reinstall install virtualbox-ose-dkms
Reading package lists… Done
Building dependency tree
Reading state information… Done
0 upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 0 not upgraded.
Need to get 0 B/550 kB of archives.
After this operation, 0 B of additional disk space will be used.
(Reading database … 133879 files and directories currently installed.)
Preparing to replace virtualbox-ose-dkms 3.2.10-dfsg-1 (using …/virtualbox-ose-dkms_3.2.10-dfsg-1_all.deb) …
——————————
Deleting module version: 3.2.10
completely from the DKMS tree.
——————————
Done.
Unpacking replacement virtualbox-ose-dkms …
Setting up virtualbox-ose-dkms (3.2.10-dfsg-1) …
Loading new virtualbox-ose-3.2.10 DKMS files…
Building only for 3.0.0-rc7+
Building initial module for 3.0.0-rc7+
Error! Bad return status for module build on kernel: 3.0.0-rc7+ (x86_64)
Consult the make.log in the build directory
/var/lib/dkms/virtualbox-ose/3.2.10/build/ for more information.
Stopping VirtualBox kernel modules.
Starting VirtualBox kernel modulesNo suitable module for running kernel found … failed!
failed!
invoke-rc.d: initscript virtualbox-ose, action “restart” failed.

If I take a look at make.log file:

volodymyr@sv1:/var/lib/dkms$ more /var/lib/dkms/virtualbox-ose/3.2.10/build/make.log
DKMS make.log for virtualbox-ose-3.2.10 for kernel 3.0.0-rc7+ (x86_64)
Tue Jul 12 16:14:57 CEST 2011
make: Entering directory `/home/volodymyr/Kernel/linux-2.6′
LD /var/lib/dkms/virtualbox-ose/3.2.10/build/built-in.o
LD /var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/built-in.o
CC [M] /var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/SUPDrv-linux.o
In file included from /var/lib/dkms/virtualbox-ose/3.2.10/build/include/VBox/types.h:30,
from /var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/../SUPDrvInternal.h:35,
from /var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/SUPDrv-linux.c:33:
/var/lib/dkms/virtualbox-ose/3.2.10/build/include/iprt/types.h:97:31: error: linux/autoconf.h: No such file or directory
/var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/SUPDrv-linux.c: In function ‘VBoxDrvLinuxInit’:
/var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/SUPDrv-linux.c:451: error: ‘nmi_watchdog’ undeclared (first use in this function)
/var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/SUPDrv-linux.c:451: error: (Each undeclared identifier is reported only once
/var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/SUPDrv-linux.c:451: error: for each function it appears in.)
/var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/SUPDrv-linux.c:451: error: ‘NMI_IO_APIC’ undeclared (first use in this function)
/var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/SUPDrv-linux.c:465: error: ‘nmi_active’ undeclared (first use in this function)
make[2]: *** [/var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv/linux/SUPDrv-linux.o] Error 1
make[1]: *** [/var/lib/dkms/virtualbox-ose/3.2.10/build/vboxdrv] Error 2
make: *** [_module_/var/lib/dkms/virtualbox-ose/3.2.10/build] Error 2
make: Leaving directory `/home/volodymyr/Kernel/linux-2.6′

There are basically two problems here. First, it tries to include linux/autoconf.h which changed location since 2.6.33 kernel. Second, by some reason it uses location of my home path for kernel sources, i.e.: /home/volodymyr/Kernel/linux-2.6

It seems like my /usr/src/linux points to my home build directory:

volodymyr@sv1:/var/lib/dkms$ ls -la /usr/src/linux
lrwxrwxrwx 1 root root 32 Jul 12 15:04 /usr/src/linux -> /home/volodymyr/Kernel/linux-2.6

Now, I can make symbolic link to avoid problem with autoconf:

ln -s /home/volodymyr/Kernel/linux-2.6/include/generated/autoconf.h /home/volodymyr/Kernel/linux-2.6/include/linux/autoconf.h

And .. it still does not work. It seems like the only way is to install VirtualBox from sid. OK, let’s remove virtualbox-ose from system and add

deb http://ftp.de.debian.org/debian sid main

To your your /etc/apt/sources.list file and do “sudo apt-get update”.

Install again virtualbox-ose (this time it is taking the sid version):

Processing triggers for python-central …
Setting up virtualbox-ose (4.0.10-dfsg-1) …
Setting up virtualbox-qt (4.0.10-dfsg-1) …
Setting up virtualbox-dkms (4.0.10-dfsg-1) …
Loading new virtualbox-4.0.10 DKMS files…
First Installation: checking all kernels…
Building only for 3.0.0-rc7+
Building initial module for 3.0.0-rc7+
Done.
vboxdrv.ko:
Running module version sanity check.
– Original module
– No original module exists within this kernel
– Installation
– Installing to /lib/modules/3.0.0-rc7+/updates/dkms/
vboxnetadp.ko:
Running module version sanity check.
– Original module
– No original module exists within this kernel
– Installation
– Installing to /lib/modules/3.0.0-rc7+/updates/dkms/
vboxnetflt.ko:
Running module version sanity check.
– Original module
– No original module exists within this kernel
– Installation
– Installing to /lib/modules/3.0.0-rc7+/updates/dkms/
depmod……………….
DKMS: install Completed.
Stopping VirtualBox kernel modules.
Starting VirtualBox kernel modules.
Setting up virtualbox-ose-dkms (4.0.10-dfsg-1) …
Processing triggers for menu …

And see that everything works okay this time.

Install Adobe Flash Player in Debian 6 Squeeze 64-bit

It seems like flash player supplied with chromium-browser does not perform job well. I frequently got “An error occured, please try again later.” which usually looks like this:

And I guess it’s time to install native 64 bit flash player in my Squeeze.

You can download experimental flash plugin for x64 Linux systems here.

Download the tar file, and untar it by right clicking on the file and selecting “Extract Archive here …” or do everything in konsole:

volodymyr@sv1:~/Downloads$ tar -zxvf flashplayer10_2_p3_64bit_linux_111710.tar.gz
volodymyr@sv1:~/Downloads$ sudo cp libflashplayer.so /usr/lib/mozilla/plugins/

That’s all 🙂 Restart iceweasel and it should work. I can’t actually take credit for this trick, it is based on this article.

P.S. If you do not hear sound from flash, make sure you have created .asoundrc file as explained here.

P.S.2 If still do not hear sound from flash, make sure you have disabled irrelevant sound devices via pavucontrol.

Why you should run ipkg upgrade with caution

I have not touched my RT-N16 (running Tomato Mod USB) for a while mostly because I don’t have a lot of time, and well, it is rock stable :). Today I decided to upgrade all my packages and I just did:

ipkg update
ipkg upgrade

And here is what I get:

Upgrading cron on /opt/ from 4.1-7 to 4.1-8...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//cron_4.1-8_mipsel.ipk
Configuration file '/opt/etc/crontab'
==> File on system created by you or by a script.
==> File also in package provided by package maintainer.
What would you like to do about it ? Your options are:
Y or I : install the package maintainer's version
N or O : keep your currently-installed version
D : show the differences between the versions (if diff is installed)
The default action is to keep your current version.
*** crontab (Y/I/N/O/D) [default=N] ?Y
Upgrading libcurl on /opt/ from 7.21.1-1 to 7.21.6-1...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//libcurl_7.21.6-1_mipsel.ipk
Upgrading libtiff on /opt/ from 3.9.4-1 to 3.9.5-1...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//libtiff_3.9.5-1_mipsel.ipk
Upgrading libxml2 on /opt/ from 2.7.7-2 to 2.7.8-1...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//libxml2_2.7.8-1_mipsel.ipk
Upgrading nmap on /opt/ from 5.21-1 to 5.35DC1-1...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//nmap_5.35DC1-1_mipsel.ipk
Upgrading pcre on /opt/ from 8.10-1 to 8.12-1...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//pcre_8.12-1_mipsel.ipk
Upgrading procmail on /opt/ from 3.22-3 to 3.22-4...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//procmail_3.22-4_mipsel.ipk
Upgrading rsync on /opt/ from 3.0.7-1 to 3.0.8-1...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//rsync_3.0.8-1_mipsel.ipk
Upgrading sane-backends on /opt/ from 1.0.21-1 to 1.0.22-1...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//sane-backends_1.0.22-1_mipsel.ipk
package sane-backends suggests installing inetutils
Configuration file '/opt/etc/sane.d/saned.conf'
==> File on system created by you or by a script.
==> File also in package provided by package maintainer.
What would you like to do about it ? Your options are:
Y or I : install the package maintainer's version
N or O : keep your currently-installed version
D : show the differences between the versions (if diff is installed)
The default action is to keep your current version.
*** saned.conf (Y/I/N/O/D) [default=N] ?Y
Upgrading vim on /opt/ from 7.3-1 to 7.3-2...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/ddwrt/cross/stable//vim_7.3-2_mipsel.ipk
Configuring cron
Remember that the system crontab file is "/opt/etc/crontab".
kill: can't kill pid 1456: No such process
Configuring libcurl
Configuring libtiff
Configuring libxml2
Configuring nmap
Configuring pcre
Configuring procmail
Configuring rsync
Configuring sane-backends

It seems you have xinetd configured and running. Good.
sane-backends has been installed and configured to run with xinetd in /opt/etc/xinetd.d/saned
Please reload xinetd to start sane-backends.
Configuring vim
Successfully terminated.

As you can see, it is complaining about two files it is going to overwrite in my configuration: /opt/etc/sane.d/saned.conf and /opt/etc/crontab. However, in fact, it also overwrote /opt/etc/xinetd.d/saned so I had to configure it back again as explained in http://www.shcherbyna.com/?p=983

New search engine: DuckDuckGo

I guess everyone have noticed lately that Google is collecting more and more information when you are doing your searches. They track your place of living, they show you custom ads, they keep your search history, your mails, etc, etc, etc.

What I never liked about Google is that by default it is unsecure. The main page http://google.com is not using https. Gmail by default does not use https unless you configure it so, etc.

Now, there is a new search engine out there: https://duckduckgo.com/.

According to their policy, they don’t do most of the things Google does: http://dontbubble.us/. And they seem to have a decent search capabilities.

Worth a try! 😉

KDE panel turns black in Debian 6.0 x86_64 (KDE 4.4.5)

I have noticed several times one bug in x86_64 Debian – your low panel turns half-black and you can do nothing about it ;). Usually it looks like this:

Now, if you adjust panel height it seems to fix the problem, however it can become black again in the future. Debian has this bug filed, but not fixed. I guess it is not fixed because it only happens in x86_64 builds. I never encountered this in x86.

The solution is to wait until the next release of KDE will be pushed in Debian, or to use a workaround which consist in removing the KDE cache content from /var/tmp/kdecache-USER_NAME.

Try to remove this folder for your user, i.e., assuming your are logged on as sheldon, perform the following:

1. rm -rf /var/tmp/kdecache-sheldon

2. log out

3. log in

If it resolves your problem, you can set to auto remove your cache when machine starts. In order to make this, add the following into your /etc/rc.local file before line “exit 0”:

rm -rf /var/tmp/kdecache-sheldon

Voilà.

What if you bricked your RT-N16 with a firmware upgrade?

Sometimes it happens that you flash your RT-N16 with corrupted firmware and you have a feeling that it is bricked :). Don’t worry, you can still try a few tricks to recover it.

In theory you should do the following:

1. Visit support page and download RT-N16 utilities and latest RT-N16 firmware. You can download them from my site: utilities and latest firmware

2. Install RT-N16 utilities and locate Firmware Restoration utility on your computer

3. Configure your network adapter to use a static IP address 192.168.1.1 and mask 255.255.255.0

4. Disable windows firewall by entering firewall.cpl in command line (this will show firewall applet and you have to disable fw there)

5. Turn off router

6. Leave only one cable in router: which connects port 1 of router with your PC.

7. Hold Reset button using some sharp tool (don’t release button!) and turn on router by plugging in power cable while holding Reset button. Notice power led is slowly blinking. Release Reset button.

8. Now run Asus Firmware Restoration Utility, specify path to Asus firmware (you can use firmware 1.0.2.3 from my blog) and click Upload

9. Firmware Restoration utility should find router and upload firmware.

This is theory. In practice, however, it did not work for me. I was doing these steps and Firmware Restoration Utility failed to detect my router, giving the message “device is not in rescue mode”. After fighting several hours I decided to do two desperate things:

1. Switch off router for 15 minutes and let it rest 🙂

2. Set adapter IP to 192.168.0.1 instead of 192.168.1.1

After this everything worked like a charm. I hope these observations will be useful for someone.

Not Idle Task tool

Sometimes it happens that you need to run a special program when you are near computer and shut it down when you leave. A typical example is winamp: you want winamp to play internet radio when you are working on machine, but when you leave it is better to shut it down – it saves a lot of your internet traffic.

So I did small tool for myself: Not Idle Task. It is pretty simple, you just need to set application to launch and when to shut it down. For example, I am listeting etn.fm, so my “application” is actually winamp with path to etn.fm play list file:

C:\Program Files (x86)\Winamp\winamp.exe “C:\Documents and Settings\volodymyr\Desktop\etn1beta.m3u”

Now, when I am idle for 120 seconds on machine I want NotIdleTask.exe to shut down winamp, so I set Idle Interval to 120. Voila:

You can download tool here: x32. It is very simple, and most likely buggy, tell me if it does not work for you.

Wake On Lan in Fedora 15 and eth0 to em1 transitions

I am using the following command to enable WOL in my Linux box:

$ sudo /sbin/ethtool -s eth0 wol g

However, after upgrade to Fedora Core 15 (FC15) I have noticed that this command fails with:

Cannot get current wake-on-lan settings: No such device
not setting wol

It seems like something have changed in FC15 and my eth0 is not anymore eth0 but em1! 🙂

$ sudo ifconfig
em1 Link encap:Ethernet HWaddr 00:22:15:88:36:BD

Okay, what I have to do to make it work in FC15 is the following:

$ sudo echo “/sbin/ethtool -s em1 wol g” > /etc/rc.d/rc.local

It seems like I am not the only one affected with this problem: http://fedoraforum.org/forum/showthread.php?t=261829

bsod offset search tool (bos) version 1.0.0.1 released

Some time ago I was writing a post about how to find a cause of bsod without having a memory dump file. I decided to implement a tool for myself which is automating these steps. If you by any chance require such a tool, it is available for download for free.

All you have to do is to give this tool three parameters: a file name (or path), a crash offset and a driver base address. It will print the hypothetical crash offset you can analyse in Ida. Here is an example screenshot.

You can download the tool from this link. If you are not sure it is safe to download from my blog, check out virustotal report on file: bos.exe.

Have fun!

Modifying EIP in WinDbg on fly in order to test different branches of code

Sometimes during debugging it happens that you just got some function failed and you want to re-try it again. After this function fails you might have a BSOD, for example,

ntRetVal = FileOpen(&hFile, szPath);

if (!NT_SUCCESS(ntRetVal))
{
#ifdef DBG
     KeBugCheckEx(0x0, 0, 0, 0, id_of_the_problem);
#endif
}

Now, as you can see in above code it is gonna bsod (in debug) if FileOpen fails. In assembler it looks like this (approximatly):

b2cefae1 8b4dec          mov     ecx,dword ptr [ebp-14h]
b2cefae4 83c114          add     ecx,14h
b2cefae7 51              push    ecx
b2cefae8 8b55ec          mov     edx,dword ptr [ebp-14h]
b2cefaeb 81c224170000    add     edx,1724h
b2cefaf1 52              push    edx
b2cefaf2 e809850200      call    mydrv!FileOpen (b2d18000)
b2cefaf7 8945f0          mov     dword ptr [ebp-10h],eax
b2cefafa 837df000        cmp     dword ptr [ebp-10h],0
b2cefafe 0f8d82000000    jge     mydrv!MyRoutine2+0x656 (b2cefb86)
b2cefb04 6a6b            push    6Bh
b2cefb06 6a00            push    0
b2cefb08 6a00            push    0
b2cefb0a 6a00            push    0
b2cefb0c 6a00            push    0
b2cefb0e ff15c841d0b2    call    dword ptr [mydrv!_imp__KeBugCheckEx (b2d041c8)]

What if you don’t want now to BSOD and loose this test-case scenario? Of course, you can repeat debugging by modifying your code and remove call to KeBugCheckEx or even add more logging. But this is waste of time. You just need to retry call to FileOpen and step further inside to see why it fails.

So, you can modify EIP on fly and set it to a call to FileOpen function. The easiest way is to open registers window (Alt + 4) or you can use r command in windbg:

0: kd> r
eax=c0000120 ebx=00000007 ecx=00000008 edx=80500021 esi=e1448598 edi=805639e4
eip=b2cefb04 esp=b25f1b68 ebp=b25f1be8 iopl=0         nv up ei ng nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000282

Now, in order to call FileOpen I have to make sure I set the EIP in proper place, exactly before it pushes params into stack, look here:

b2cefae1 8b4dec          mov     ecx,dword ptr [ebp-14h]
b2cefae4 83c114          add     ecx,14h
b2cefae7 51              push    ecx
b2cefae8 8b55ec          mov     edx,dword ptr [ebp-14h]
b2cefaeb 81c224170000    add     edx,1724h
b2cefaf1 52              push    edx
b2cefaf2 e809850200      call    mydrv!FileOpen (b2d18000)

So, we have to set EIP to point to b2cefae1. You can modify EIP value in Registers window or you can set it via command line:

0: kd> r EIP=b2cefae1

Press F10 and you will see that the flow of execution will change. You can basically use this technique even in user mode debugging in Visual Studio (registers window), just make sure you don’t wack the stack, i.e., change EIP before your code pushes some params into stack, otherwise your stack will be bogus. In order to achieve this, switch to disassembly view from source view so that you would not miss any commands by pressing F10.

You can say: “what about Edit -> Set Current Instruction menu item in Windbg? Isn’t modifying registers more complex?” Indeed, it is. However, it gives you more control.

Imagine that you decided to change EIP by choosing “Set Current Instruction” menu item in Windbg, but before you chooose this item, you were in the middle of pushing to stack params to some function, i.e.,

b2cefb21 6a6b            push    6Bh <------- you are executing this instruction
b2cefb23 6a00            push    0
b2cefb25 6a00            push    0
b2cefb27 6a00            push    0
b2cefb29 6a00            push    0
b2cefb2b ff15c841d0b2    call    dword ptr [mydrv!_imp__KeBugCheckEx (b2d041c8)]

At this situation if you change EIP you will have in stack 1 dword: 6bh (4 bytes). Now, suppose you change EIP and execution flow goes somewhere, after you desired function worked out, these 4 bytes in stack are not going to be pop-ped out and you have to do something with them, as they eventually will cause problems.

In these situations you will have to adjust stack by … modifying ESP register! In this particular case in order to remove 4 bytes from stack you can do the following:

r ESP=@esp + 4

As you can see, even if you use “Set Current Instruction” you still may need to care about modifying registers, so why just not take this approach from the begining and consider accuratly all modifications you perfom? 🙂

How to find cause of BSOD without dump file

Sometimes it happens that BSOD occures without any dump file generated. It could take some time to figure out why there is no dump file generated and what to do. If this happens on customer side, sometimes it is really problematic due to different policies, restrictions, etc.

On the other hand, it is possible to have a clue about BSOD even without memory dump file. For this, you have to know the load address of your driver and offset where problem occured. Luckily, Windows provides this information when printing BSOD information on screen.

Usually, a typical BSOD looks like this:

As you can see, you have a crash address 919C3763 and base address 919B4000. Now, assuming you know exact version of your driver installed on this machine you can use IDA to disassemble it and analyze “the problematic place”.

First, we need to calculate RVA address where crash occures. This is easy: RVA = 919C3763 – 919B4000 ; RVA = F763 . Second, you need to fire-up Ida and disassemble your driver. When analysys finishes, go to header of file and look at imagebase value:

Now, having imagebase which is equal 10000 for this case, you have to calculate offset where crash occured:

Offset = ImageBase + RVA ; Offset = 10000 + F763; Offset = 1F763

Now, press “G” in Ida, and enter value 1F763:

If everything is done properly, you should see the faulty instruction. Of course, if you have symbols, it is much easier to analyse code, but even without symbols, you can recognize your code and have a clue what can go wrong.

Why calling WTSEnumerateSessions in NT service initialization routine is a bad idea

Recently in tests I noticed that my NT service stopped working in Windows Vista machine. There were no crashes, just entry in Event Log saying: “Error 1053: The service did not respond to the start or control request in a timely fashion“.

These type of things are slightly more difficult to debug than usual crashes because usually you have no crash address and no dump generated by WER. At the same time, I had a suspicious feeling that it could be related to initialization of my global object, as it’s constructor function is quite big.

For the sake of the test, I put some logging into my main(…) function and noticed that nothing was logged – entry point of service was not even called. Okay, most likely problem is indeed caused by code in constructors.

These kind of errors are better to debug using WinDbg, because service starts really early, therefore standard debugging would not work.

So, the general approach is to:

1. Setup WinDbg debugging with vmmon to boost debugging speed

2. Put calls to DebugBreak(…) into constructors in your service

3. Reboot machine, and wait until it breaks in debugger

Once it breaks, one has to “attach” to a current process using the following commands in Windbg (otherwise you will be unable to step into your code, which is quite inconvenient, right?):

0: kd> !process
PROCESS 83534d90  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000

0: kd> .process /p /r 83534d90

Implicit process is now 83534d90
.cache forcedecodeuser done
Loading User Symbols

Now, if you’ve done everything properly, you should be able to see your code and normally debug it. Using this technique, I was able to narrow down issue to a call WTSEnumerateSessions(…) which hangs, therefore, CRT does not pass control to entry point of service, and SCM “thinks” it time-outs.

What is so special in this function which makes it hung? Let us take a look at documentation:

To enumerate a session, you must have Query Information permission. For more information, see Remote Desktop Services Permissions. To modify permissions on a session, use the Remote Desktop Services Configuration administrative tool.

To enumerate sessions running on a virtual machine hosted on a RD Virtualization Host server, you must be a member of the Administrators group on the RD Virtualization Host server.

There is nothing about why it could hang, or take long time to execute. Let’s take a look at it’s internals. Fire up Ida:

.text:49CB2CC9 _WTSEnumerateSessionsA@20 proc near

[...]

.text:49CB2CFE                 lea     eax, [ebp+arg_0]
.text:49CB2D01                 push    eax
.text:49CB2D02                 lea     eax, [ebp+var_4]
.text:49CB2D05                 push    eax
.text:49CB2D06                 push    [ebp+arg_0]
.text:49CB2D09                 call    _WinStationEnumerateW@12 ; WinStationEnumerateW(x,x,x)
.text:49CB2D0E                 test    al, al

As you can see above, a call to WTSEnumerateSessions actually maps into winsta.dll!WinStationEnumerate. OK, fire-up another instance of Ida and disassemble winsta.dll:

.text:410456C4 ; __stdcall WinStationEnumerateW(x, x, x)

[...]

.text:410456C4
.text:410456C4 ; FUNCTION CHUNK AT .text:4104C405 SIZE 00000030 BYTES
.text:410456C4
.text:410456C4                 mov     edi, edi
.text:410456C6                 push    ebp
.text:410456C7                 mov     ebp, esp
.text:410456C9                 push    esi
.text:410456CA                 push    [ebp+arg_8]
.text:410456CD                 push    [ebp+arg_4]
.text:410456D0                 push    [ebp+arg_0]
.text:410456D3                 call    ?_tsrpcEnumerate@@YGJPAXPAPAU_SESSIONIDW@@PAK@Z

As we can see, WinStationEnumerate calls internally _tsrpcEnumerate function which looks like this:

.text:41045729                 push    dword ptr [ebp+8]
.text:4104572C                 lea     ecx, [ebp-54h]
.text:4104572F                 call    ??0CSmartPublicBinding@@QAE@PAXH@Z ; CSmartPublicBinding::CSmartPublicBinding(void *,int)
.text:41045734                 push    1
.text:41045736                 push    dword ptr [ebp+8]
.text:41045739                 lea     ecx, [ebp-48h]
.text:4104573C                 call    ??0CSmartPublicBinding@@QAE@PAXH@Z ; CSmartPublicBinding::CSmartPublicBinding(void *,int)
.text:41045741                 lea     ecx, [ebp-54h]
.text:41045744                 call    ??BCSmartPublicBinding@@QAEPAXXZ ; CSmartPublicBinding::operator void *(void)
.text:41045749                 test    eax, eax
.text:4104574B                 jz      loc_4104CFA8
.text:41045751                 lea     ecx, [ebp-54h]
.text:41045754                 call    ??BCSmartPublicBinding@@QAEPAXXZ ; CSmartPublicBinding::operator void *(void)
.text:41045759                 push    eax
.text:4104575A                 lea     ecx, [ebp-34h]
.text:4104575D                 call    ?Open@CEnum@@QAEJPAX@Z ; CEnum::Open(void *) <--------------------- look here

After some analysis of the function body I eventually see that inside CEnum::Open method there is the following call:

.text:4104561D ?Open@CEnum@@QAEJPAX@Z proc near        ; CODE XREF: _tsrpcEnumerate(void *,_SESSIONIDW * *,ulong *)
.text:4104561D                 push    10h
.text:4104561F                 push    offset dword_41045678 ; char
.text:41045624                 call    __SEH_prolog4
.text:41045629                 mov     esi, ecx
.text:4104562B                 push    offset aCenumOpen ; "CEnum::Open"
.text:41045630                 push    10h             ; int
.text:41045632                 call    ?_DbgPrintMessage@@YAXHPBDZZ ; _DbgPrintMessage(int,char const *,...)
.text:41045637                 pop     ecx
.text:41045638                 pop     ecx
.text:41045639                 and     dword ptr [ebp-4], 0
.text:4104563D                 push    esi
.text:4104563E                 push    dword ptr [ebp+8]
.text:41045641                 call    _RpcOpenEnum@8  ; RpcOpenEnum(x,x) <--------------------- look here
.text:41045646                 mov     [ebp-1Ch], eax
.text:41045649
.text:41045649 loc_41045649:                           ; CODE XREF: .text:4104C11Ej
.text:41045649                 mov     dword ptr [ebp-4], 0FFFFFFFEh
.text:41045650                 push    offset aCenumOpen ; "CEnum::Open"
.text:41045655                 push    20h             ; int
.text:41045657                 call    ?_DbgPrintMessage@@YAXHPBDZZ ; _DbgPrintMessage(int,char const *,...)
.text:4104565C                 pop     ecx
.text:4104565D                 pop     ecx
.text:4104565E                 mov     eax, [ebp-1Ch]
.text:41045661                 call    __SEH_epilog4
.text:41045666                 retn    4
.text:41045666 ?Open@CEnum@@QAEJPAX@Z endp ; sp = -8

As we can see here, there is a call to RpcOpenEnum(…) function. Well, as it smells RPC, most likely, it is not yet initialized at this point. In order to prove this idea, I setup dependency to service RpcSS, restart machine, and voila, everything works.

The most interesting part is that documentation for WTSEnumerateSessions does not mention any limitations about early calls, RPC time-outs, etc. Of course, one has to be extremly careful when runing services at early boot time, but having a reminder in documentation for API function(s) would be nice to have.

Btw, here is a nice list of dependencies to rpcss: http://technet.microsoft.com/en-us/library/cc787851%28WS.10%29.aspx by Windows services.

Donating CPU to science

(… and counting …)

Long time ago I was searching in internet for any “mass projects” to participate in and make something useful for the society. And I’ve found BOINC project: a generic platform for scientific computations.

Among several projects I was attracted by MilkyWay – an internet-based public distributed computing project attempting to generate highly accurate three-dimensional dynamic models of stellar streams in the immediate vicinity of our Milky Way galaxy: http://milkyway.cs.rpi.edu/milkyway. While being very CPU intensive I have something to proud of – my computer is useful when it’s idle … What about yours?

P.S. After some googling I’ve found a ukrainian distributed calculations team: http://distributed.org.ua/ which is quite active in milkyway project aswell: http://distributed.org.ua/index.php?go=Pages&in=view&id=159

Update: I found team “Ukraine” in MilkyWay: http://milkyway.cs.rpi.edu/milkyway/team_display.php?teamid=120 😉 Join it and support national team!

As you can see from statistics, my contribution to team “Ukraine” is less than 1% for almost one year of contribution 😉 It is hell small 🙂

Compiling Dropbox client under Debian Squeeze

I was recently invited into Dropbox cloud file sharing service by a friend of mine and as it usually happens – you can install client easy in Ubuntu and Fedora, but not in Debian :).

To be more precise, Dropbox ships only deb file for Ubuntu, which did not work for me, because of the depenendy to libnautilus-extension1 library:

$ sudo dpkg -i nautilus-dropbox_0.6.7_i386.deb
Selecting previously deselected package nautilus-dropbox.
(Reading database ... 176727 files and directories currently installed.)
Unpacking nautilus-dropbox (from nautilus-dropbox_0.6.7_i386.deb) ...
dpkg: dependency problems prevent configuration of nautilus-dropbox:
nautilus-dropbox depends on libnautilus-extension1 (>= 1:2.22.2); however:
Version of libnautilus-extension1 on system is 2.30.1-2.
dpkg: error processing nautilus-dropbox (--install):
dependency problems - leaving unconfigured
Processing triggers for hicolor-icon-theme ...
Processing triggers for man-db ...
Errors were encountered while processing:
nautilus-dropbox

But one can try to compile it from sources and it seems to work for me. Download and extract sources from: here.

Now, install necessary library requirements:

sudo apt-get -f install
sudo apt-get install libnautilus-extension-dev
sudo aptitude install python-docutils

After this try to compile dropbox:

./configure
make
sudo make install

If compilation does not break, you should have Dropbox icon in your menu under Internet section (I use KDE) and in system tray.