Skip to content

Twitter icon Follow me?

10 Jun http://t.co/48vDqcXDKh has periodically responded with HTTP 503 for the last days. Troubleshooting and fixing it now.

05 Jun URLs on http://t.co/DUQ10jxV2s now includes the file name. e.g. /file/avgrsx.exe-87518/ instead of /file/87518/. Might improve Google rank.

30 May Sigh. Pollen in my laptop display, again :( http://t.co/2CtDVd392f

30 May Scrolls will go public Beta the 3rd of June: http://t.co/2cS1t47jgH

30 May I should put the filename into the URL for better search engine placement: http://t.co/S1OJYBUhP5

27 May I've improved the caching on the FreeFixer web site. Hopefully it will respond quicker now. Please let me know if anything is slow.

23 May http://t.co/48vDqcXDKh is down for maintenance this morning. Should be back online in 5 minutes.

15 May DreamHost have had some connectivity issues with the datacenter where my sites are located. Seems to be online again now.

08 Apr Thank you Glen Haar for your FreeFixer donation!

02 Apr Google Code Jam 2013. Anyone participating? http://t.co/0w5469rYok

27 Mar FreeFixer v1.04 released. This version scans your Internet Explorer extensions: http://t.co/h5aQtL7nOP

25 Mar FreeFixer v1.04 released soonish. It will scan your Internet Explorer extensions. http://t.co/BWYqkVAYZc

12 Feb FreeFixer v1.03 released: http://t.co/w7FQVSPU

01 Feb FreeFixer can now continuously monitor system changes on your computer by running periodic background scans: http://t.co/fQizCL9x

Development Diary 2012

Here's my software development diary. Hope you'll find some useful information here. Feel free to comment.

26 September 2012

How to run a program as a limited user on Windows XP

The following command line starts a command shell with the same rights as a limited user:

PsExec.exe -l -d c:\windows\system32\cmd.exe

Creating a desktop shortcut with the above command line can be quite useful when you want to start a program repeatedly as a limit user. In my case, I'm using PsExec to run the unit tests without the administrative privileges. You can download PsExec at the SysInternal's web site.

18 June 2012

Named return value optimization

The other day a colleague and I were debating if a piece of code written like this:

vector<string> GetTheVector()
{
	vector<string> v;
	v.reserve(..)
	v.push_back(..) //push back the # reserved strings.
	return v;
}

Could be rewritten like follows to reduce the number of memory allocations:

void GetTheVector(vector<string>& v)
{
	//caller has already called v.reserve(..)
	v.push_back(..) //push back the # reserved strings.
}

I've written a code snippet below which overrides operator new to count the number of memory allocations. At least in Visual Studio 2005 the number of memory allocations for the two variants are the same. Feel free to post the results for the compiler you are using.

#include <new>

size_t g_num_allocs = 0;

void* operator new(std::size_t size)
{
	++g_num_allocs;
	return malloc(size);
}

void* operator new(std::size_t size,
                   const std::nothrow_t &) throw()
{
	++g_num_allocs;
	return malloc(size);
}

void* operator new[](std::size_t size)
{
	++g_num_allocs;
	return malloc(size);
}

void* operator new[](std::size_t size,
                     const std::nothrow_t &) throw()
{
	++g_num_allocs;
	return malloc(size);
}

void operator delete(void *pMem) throw()
{
	if (pMem) free(pMem);
}

void operator delete(void *pMem,
                     const std::nothrow_t &) throw()
{
	if (pMem) free(pMem);
}

void operator delete[](void *pMem) throw()
{
	if (pMem) free(pMem);
}

void operator delete[](void *pMem,
                       const std::nothrow_t &) throw()
{
	if (pMem) free(pMem);
}

#include <cstdlib>
#include <vector>
#include <string>

using namespace std;

const char* g_string = "012345678901234567890123456789";

vector<string> test0()
{
	vector<string> v;
	v.reserve(5);

	v.push_back(g_string);
	v.push_back(g_string);
	v.push_back(g_string);
	v.push_back(g_string);
	v.push_back(g_string);

	return v;
}

void test1(vector<string>& v)
{
	v.push_back(g_string);
	v.push_back(g_string);
	v.push_back(g_string);
	v.push_back(g_string);
	v.push_back(g_string);
}

int main(int argc, char* argv[])
{
	{
		g_num_allocs = 0;

		const vector<string>& v = test0();
		printf("# new in test0: %d\n", g_num_allocs);

		printf("v[0]=%s\n\n", v[0].c_str());
	}

	{
		g_num_allocs = 0;

		vector<string> v;
		v.reserve(5);
		test1(v);
		printf("# new in test1: %d\n", g_num_allocs);

		printf("v[0]=%s\n\n", v[0].c_str());
	}

	return 0;
}

/* Outputs:

Compiler: Visual studio 2005
Compiler flags /O2 /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" 
               /D "_UNICODE" /D "UNICODE" /FD /EHsc /MT 
               /Fo"Release\\" /Fd"Release\vc80.pdb" /W3 
               /nologo /c /Wp64 /Zi /TP /errorReport:prompt

# new in test0: 11
v[0]=012345678901234567890123456789

# new in test1: 11
v[0]=012345678901234567890123456789

*/
02 June 2012

Some symbols not found when debugging a mini-dump

I'm currently looking at a user's crash dump and noticed that I did not get a complete call stack. This usually happens when symbols are not loaded for all modules that participate in the callstack. The Output window in Visual Studio reports missing symbols for wininet.dll, normaliz.dll, urlmon.dll, iertutil.dll and ieframe.dll which is suprising since I've set up Visual Studio to download symbols from http://msdl.microsoft.com/download/symbols.

Anyone else run into this problem? Could the issue be that the files have been modified on the user's machine so the checksum does not match any known symbols at the symbol servers, or is there any additional symbol servers URL that should be specified?

Visual Studio Output

wininet.dll *C:\WINDOWS\system32\wininet.dll N/A N/A No matching binary found. 4 8.00.6001.18702 3/8/2009 1:34 PM 63000000-630E6000 freefixer.0.62.dmp: Native

ntdll.dll C:\tmp\symbolcache\ntdll.dll\4802c25eb6000\ntdll.dll Symbols loaded (source information stripped). C:\tmp\symbolcache\ntdll.pdb\1751003260CA42598C0FB326585000ED2\ntdll.pdb 2 5.01.2600.5512 4/14/2008 4:33 AM 7C910000-7C9C6000 freefixer.0.62.dmp: Native

Broken call stack

ieframe.dll!01e8ffec() 	
shell32.dll!CRegFolder::BindToObject()  + 0x32 bytes	
shell32.dll!CWebViewFolderContents::CConnectionPointForwarder::Release()  + 0x11 bytes	
ntdll.dll!_RtlFreeHeap@12()  + 0x130 bytes	
ieframe.dll!01e8ffec() 	
shell32.dll!CRegFolder::BindToObject()  + 0x32 bytes	
shell32.dll!CWebViewFolderContents::CConnectionPointForwarder::Release()  + 0x11 bytes	
ntdll.dll!_RtlFreeHeap@12()  + 0x130 bytes

Permalink | Comments

07 June 2010

Crash in CDHtmlDialog's OnInitDialog method

Recently I implemented a crash report system for FreeFixer which allows the user to upload the FreeFixer memory dump for analysis. A memory dump is generated if an unhandled exception occur, such as an access violation exception, or if the application triggers an ASSERT. With the help of the memory dump, FreeFixer's executable file, and the symbols, I can see exactly where in the code the problem occur. This have been quite useful to track down some bugs.

Today I downloaded the 10 dumps generated from FreeFixer v0.58 for analysis. There has been approximately 20.000 downloads since the release of FreeFixer v0.58 three weeks ago. There are two bugs that has been around for some time where I've not found any fix.

Five of the dumps highlights a problem that appears during initialization. FreeFixer's user interface is built with a CDHtmlDialog. When the application starts, I call the dialog's DoModal() method, which later on calls my OnInitDialog() method, which immediately calls CDHtmlDialog::OnInitDialog.

BOOL CDHtmlDialog::OnInitDialog()
{
	AfxEnableControlContainer();

	CDialog::OnInitDialog();

	RECT rectClient;
	GetClientRect(&rectClient);

	// if we've been created from the dynamic template
	// set the caption
	if (!m_lpszTemplateName)
		SetWindowText(m_strDlgCaption);

	// check if there is a browser control on the dialog
	// already
	CWnd *pCtrl = GetDlgItem(AFX_IDC_BROWSER);
	LPUNKNOWN lpUnk;
	if (pCtrl)
	{
		lpUnk = pCtrl->GetControlUnknown();
		if (lpUnk && SUCCEEDED(lpUnk->QueryInterface(IID_IWebBrowser2, (void **) &m_pBrowserApp)))
		{
			m_wndBrowser.Attach(pCtrl->m_hWnd);
			m_bAttachedControl = TRUE;
		}
	}
	if (m_pBrowserApp == NULL)
	{
		// create the control window
		m_wndBrowser.CreateControl(CLSID_WebBrowser, NULL,
					WS_VISIBLE | WS_CHILD, rectClient, this, AFX_IDC_BROWSER);
		lpUnk = m_wndBrowser.GetControlUnknown();
boom->		if (FAILED(lpUnk->QueryInterface(IID_IWebBrowser2, (void**) &m_pBrowserApp)))
		{
			m_wndBrowser.DestroyWindow();
			DestroyWindow();
			return TRUE;
		}

In the code listed above, m_wndBrowser.GetControlUnknown() returns NULL and is assigned to the lpUnk variable, and later on a call to lpUnk->QueryInterface is done. There we have an access violation exception. Unfortunately I've not been able to figure out why does problem appear, and why it only appears in 1 out of 4000 downloads. Do you know of a solution to this problem? Please let me know.

There are a few suggestions available to fix this problem, such as calling CoInitialize(NULL) or AfxEnableControlContainer() in the application's InitInstance() method. However, none of these fixes has solved the problem:

The 5 remaining dumps is related to FreeFixer's code that extracts icons from executable files which are displayed in the scan result. The code goes something like this:

HMODULE module = LoadLibraryEx(filename, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (!module) return;

[..do some work on the module..]

const BOOL result = FreeLibrary(module);
ASSERT(result);

The result from FreeLibrary is passed to the ASSERT macro since I assume it is programming error if FreeLibrary fails when passed a valid HMODULE. However, the assertion is triggered, approximately once every 4000 downloads. Unfortunately I don't have the file name of the module that the code loads which probably would give some hints why the problem occur. Another interesting observation is that all five dumps shows that the machines where running the BitDefender anti-virus. Anyone else noticed this problem?

Permalink | Comments

23 April 2009

Porting Native API calls to Windows 7

I'm currently porting FreeFixer for the Windows 7 platform. Luckily the different flavors of Windows does not differ that much from one release to another, so most of the unit tests worked without any changes to the existing code.

There's one piece of code that needed an update though, and it's the rootkit detection plugin, which in its current state detects hidden processes. This plugin uses the Windows Native API. The Native API is incompletely documented and used internally by the Windows NT operating systems (NT, XP, 2000, Vista, Win7, etc). FreeFixer calls the Native API by putting the system calls index in the eax register, and then using sysenter or int 2Eh depending on the platform. By using this procedure, FreeFixer can bypass some of the rootkit hooking techniques that hide running processes.

There is one problem though, the system call index numbers have changed from release to release, and Windows 7 was not exception, so the code needed an update. The following lists some of the index numbers for the Windows 7 platform:

NtQuerySystemInformation  = 0x106
NtQueryInformationProcess = 0xe4
NtReadVirtualMemory       = 0x105
NtOpenProcess             = 0xbf

Hope this helps if you are porting your Native API calls to Windows 7.

Permalink | Comments

20 February 2009

OpenProcess and Audiodg.exe

I'm currently working on getting my malware removal tool FreeFixer up and running on the Windows Vista platform. FreeFixer woks by scanning the registry and the file system to find unwanted software. It is also enumerating processes, their file names and their modules. This is were I ran into some minor problem. On Windows XP I had previously obtained the SeDebugPrivilege privilege (defined as SE_DEBUG_NAME) and then opened all processes with the OpenProcess system call and passing PROCESS_QUERY_INFORMATION | PROCESS_VM_READ as the requested access. However, on Windows Vista OpenProcess failed on Audiodg.exe, with the ERROR_ACCESS_DENIED error code.

Audiodg.exe - a protected process

Windows Vista introduced a new type of process, the protected process. Protected processes are there to enhance support for digital rights management functionality in Windows Vista. [1]

A typical protected process does not allow injecting a thread into the process, accessing virtual memory of process, debugging the process, duplicate handles of the process, changing the quota or working set of a process.
You cannot open a typical protected process with PROCESS_QUERY_INFORMATION nor PROCESS_VM_READ. Luckily Vista introduced the PROCESS_QUERY_LIMITED_INFORMATION, which is a limited version of the PROCESS_QUERY_INFORMATION access right. This will allow you to open the process with OpenProcess and at least get the full path of the protected process. I think - please correct me if I'm wrong - that it's not possible to enumerate the modules of audiodg.exe from without the help of a kernel-mode component?

Permalink | Comments