<?xml version="1.0"?>
<rss version="2.0">
    <channel>
        <title>OpenRCE: Blog</title>
        <link>http://www.openrce.org/rss/feeds/blog</link>
        <description>OpenRCE: The Open Reverse Code Engineering Community</description>
                <item>
            <title>StackWatcher (French)</title>
                            <pubDate>Thu, 28 Dec 2006 11:23:59 -0600</pubDate>
                                        <link>https://www.openrce.org/blog/view/561/StackWatcher_(French)</link>
                                        <author>CrazYvan &lt;email-suppressed@example.com&gt;</author>
                                                    <description>Plop, c'est les vacances et IvanleMad ne peut s'arr&ecirc;ter de coder, toujours en&lt;br /&gt;
qu&ecirc;te de satisfation personnelle, la masturbation ne lui suffit plus il doit &lt;br /&gt;
coder, toujours plus vite, toujours plus loin, toujours plus profond.&lt;br /&gt;
&lt;br /&gt;
Ainsi dans ces p&eacute;r&eacute;grinations il jouait avec le fameux tools de Mark &lt;br /&gt;
Russinovitch, Process Explorer, et tombe sur une fonction permettant de voir la &lt;br /&gt;
pile d'appel d'un Thread, son esprit commenca &agrave; entr&eacute; en &eacute;ruption. &amp;quot;Comment ce &lt;br /&gt;
put1 de b4t@rd de ca race de programme fonctionne ffs ?!&amp;quot;. Cet ainsi qu'il &lt;br /&gt;
d&eacute;cida &agrave; reverse l'irr&eacute;versible (O_o).&lt;br /&gt;
&lt;br /&gt;
Effectivement apr&egrave;s cette superbe intro r&eacute;alis&eacute;e par mon Dr Hide, je vous &lt;br /&gt;
propose un tool, cod&eacute; par mes soins. Son objectif ! Etre capable de lire la &lt;br /&gt;
m&eacute;moire d'un autre process afin de parcourir la pile de chaque thread et d'y &lt;br /&gt;
retrouver les fonctions utilis&eacute;es. Cela para&icirc;t dingue mais c'est faisable, si le &lt;br /&gt;
tool du ruskoff est capable de le faire alors pourquoir pas le mien :]&lt;br /&gt;
Bon en lisant la doc des API d'aide au d&eacute;buggage je suis tomb&eacute; sur&amp;nbsp;&amp;nbsp;&lt;br /&gt;
StackWalk64(), une API permettant de retrouver les appels &agrave; partir de la pile, &lt;br /&gt;
il suffit de lui donner un HANDLE sur le process, un autre sur le Thread stop&eacute; &lt;br /&gt;
au pr&eacute;alable, quelques infos sur l'&eacute;tat du Thread et hop (burp!) elle se &lt;br /&gt;
d&eacute;brouille pour nous retrouver les saved eip, W00t.&lt;br /&gt;
&lt;br /&gt;
Comme c'est nowel je me suis que c'etait bien joli d'avoir les addr d'appel, &lt;br /&gt;
mais que ca serait encore mieux d'avoir les noms de ces fonctions. Le programme &lt;br /&gt;
utilise donc les symbols, fournit par MS, qui doivent &ecirc;tre downloader sur son &lt;br /&gt;
site avec les debugings tools, ici : &lt;br /&gt;
http://www.microsoft.com/whdc/devtools/debugging/default.mspx&lt;br /&gt;
&lt;br /&gt;
Je peux vous dire que cela ma pas prit la t&ecirc;te pour faire marcher ce petit bout &lt;br /&gt;
de code, la doc sur le net n'&eacute;tant pas foisonnante ....&lt;br /&gt;
&lt;br /&gt;
------------CUT HERE--------------------&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
#include &amp;lt;windows.h&amp;gt;&lt;br /&gt;
#include &amp;lt;tlhelp32.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dbghelp.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#pragma comment (lib, &amp;quot;advapi32.lib&amp;quot;)&lt;br /&gt;
#pragma comment (lib, &amp;quot;dbghelp.lib&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
int NameToPid(char *ProcessName)&lt;br /&gt;
{&lt;br /&gt;
	HANDLE hProcessSnap;&lt;br /&gt;
	PROCESSENTRY32 pe32;&lt;br /&gt;
&lt;br /&gt;
	hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);&lt;br /&gt;
	if(hProcessSnap==INVALID_HANDLE_VALUE)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Error with CreateToolhelp32Snapshot: 0x%x\n&amp;quot;,GetLastError() );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	pe32.dwSize = sizeof(PROCESSENTRY32);&lt;br /&gt;
&lt;br /&gt;
	if( !Process32First(hProcessSnap, &amp;amp;pe32 ))&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Error with Process32First: %d\n&amp;quot;,GetLastError());&amp;nbsp;&amp;nbsp;&lt;br /&gt;
		CloseHandle(hProcessSnap);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	while(Process32Next(hProcessSnap,&amp;amp;pe32)!=0) &lt;br /&gt;
	{&lt;br /&gt;
 		if(_stricmp(pe32.szExeFile,ProcessName)==0) //_stricmp fuck la case sensitive&lt;br /&gt;
 		{&lt;br /&gt;
 			CloseHandle(hProcessSnap);&lt;br /&gt;
 			return pe32.th32ProcessID;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseHandle(hProcessSnap);&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DWORD EnablePrivilege(char *Privilege)&lt;br /&gt;
{&lt;br /&gt;
	HANDLE hToken;&lt;br /&gt;
	DWORD Ret=1;&lt;br /&gt;
	TOKEN_PRIVILEGES TP;&lt;br /&gt;
	LUID Luid;&lt;br /&gt;
	&lt;br /&gt;
	if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &amp;amp;hToken))&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Error with OpenProcessToken: %d\n&amp;quot;, GetLastError());&lt;br /&gt;
		Ret=0;&lt;br /&gt;
		goto bye;	&lt;br /&gt;
	} &lt;br /&gt;
	&lt;br /&gt;
	if(!LookupPrivilegeValue(NULL, Privilege, &amp;amp;TP.Privileges[0].Luid))&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Error with LookupPrivilegeValue: %d\n&amp;quot;, GetLastError());&lt;br /&gt;
		Ret=0;&lt;br /&gt;
		goto bye;	&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	TP.PrivilegeCount=1;&lt;br /&gt;
	TP.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;&lt;br /&gt;
	&lt;br /&gt;
	if(!AdjustTokenPrivileges(hToken,&lt;br /&gt;
							false,&lt;br /&gt;
							&amp;amp;TP,&lt;br /&gt;
							NULL,&lt;br /&gt;
							NULL,&lt;br /&gt;
							NULL))&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Error with AdjustTokenPrivileges: %d\n&amp;quot;, GetLastError());&lt;br /&gt;
		Ret=0;&lt;br /&gt;
		goto bye;	&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	bye:&lt;br /&gt;
	if(hToken)&lt;br /&gt;
		CloseHandle(hToken);&lt;br /&gt;
	&lt;br /&gt;
	return Ret;	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char * argv[])&lt;br /&gt;
{&lt;br /&gt;
	HANDLE hProcess, hThread, hThreadSnap;&lt;br /&gt;
	DWORD PID, TID;&lt;br /&gt;
	DWORD64 Displacement;&lt;br /&gt;
	THREADENTRY32 Th32;&lt;br /&gt;
	STACKFRAME64 StackFrame;&lt;br /&gt;
	IMAGEHLP_MODULE64 IM;&lt;br /&gt;
	CONTEXT Context;&lt;br /&gt;
	PSYMBOL_INFO pSI;&lt;br /&gt;
	&lt;br /&gt;
	SymSetOptions(SYMOPT_UNDNAME|SYMOPT_DEFERRED_LOADS);&lt;br /&gt;
&lt;br /&gt;
	RtlSecureZeroMemory(&amp;amp;Th32, sizeof(THREADENTRY32));&lt;br /&gt;
	RtlSecureZeroMemory(&amp;amp;IM, sizeof(IMAGEHLP_MODULE64));&lt;br /&gt;
	&lt;br /&gt;
	IM.SizeOfStruct=sizeof(IMAGEHLP_MODULE64);&lt;br /&gt;
	&lt;br /&gt;
	if(argc!=2)&lt;br /&gt;
		return 0;&lt;br /&gt;
	&lt;br /&gt;
	PID=NameToPid(argv[1]);&lt;br /&gt;
	if(!PID)&lt;br /&gt;
	{ &lt;br /&gt;
		printf(&amp;quot;Error with NameToPid : %d\n&amp;quot;, GetLastError());&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//pour les process system&lt;br /&gt;
	EnablePrivilege(&amp;quot;SeDebugPrivilege&amp;quot;);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
	hProcess=OpenProcess(PROCESS_VM_OPERATION|&lt;br /&gt;
						PROCESS_VM_WRITE|&lt;br /&gt;
						PROCESS_VM_READ|&lt;br /&gt;
						PROCESS_CREATE_THREAD|&lt;br /&gt;
						PROCESS_QUERY_INFORMATION,&lt;br /&gt;
	 					FALSE, PID);&lt;br /&gt;
	if(!hProcess)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Error with OpenProcess : %d\n&amp;quot;, GetLastError());&lt;br /&gt;
		goto cleanup;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/*&lt;br /&gt;
	fInvadeProcess &lt;br /&gt;
	[in] If this value is TRUE, enumerates the loaded modules for the process and effectively &lt;br /&gt;
	calls the SymLoadModule64 function for each module. &lt;br /&gt;
	*/&lt;br /&gt;
	if(!SymInitialize(hProcess, NULL, true))&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Error with SymInitialize : %x\n&amp;quot;, GetLastError());&lt;br /&gt;
		goto cleanup;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	hThreadSnap=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);&lt;br /&gt;
	Th32.dwSize=sizeof(THREADENTRY32);&lt;br /&gt;
&lt;br /&gt;
	if(!Thread32First(hThreadSnap,&amp;amp;Th32))&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Error with Thread32First : %d\n&amp;quot;, GetLastError());&lt;br /&gt;
		goto cleanup;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//on se place sur le 1er thread de notre process&lt;br /&gt;
	while(Th32.th32OwnerProcessID!=PID)&lt;br /&gt;
		Thread32Next(hThreadSnap,&amp;amp;Th32);&lt;br /&gt;
	&lt;br /&gt;
	pSI=(PSYMBOL_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SYMBOL_INFO)+MAX_SYM_NAME);&lt;br /&gt;
	if(!pSI)&lt;br /&gt;
		goto cleanup;&lt;br /&gt;
	&lt;br /&gt;
	//tant que le thread appartient au process &lt;br /&gt;
	while(Th32.th32OwnerProcessID==PID)&lt;br /&gt;
	{&lt;br /&gt;
		TID=Th32.th32ThreadID;&lt;br /&gt;
		printf(&amp;quot;\nThread ID : %d\n&amp;quot;, TID);&lt;br /&gt;
		&lt;br /&gt;
		RtlSecureZeroMemory(pSI, sizeof(SYMBOL_INFO)+MAX_SYM_NAME);&lt;br /&gt;
		pSI-&amp;gt;SizeOfStruct=sizeof(SYMBOL_INFO);&lt;br /&gt;
		pSI-&amp;gt;MaxNameLen=MAX_SYM_NAME;&lt;br /&gt;
		&lt;br /&gt;
		RtlSecureZeroMemory(&amp;amp;Context, sizeof(CONTEXT));&lt;br /&gt;
		//EIP, EBP, ESP&lt;br /&gt;
		Context.ContextFlags=CONTEXT_CONTROL;&lt;br /&gt;
		&lt;br /&gt;
		RtlSecureZeroMemory(&amp;amp;StackFrame, sizeof(STACKFRAME64));&lt;br /&gt;
	&lt;br /&gt;
		hThread=OpenThread(THREAD_QUERY_INFORMATION|THREAD_SUSPEND_RESUME|THREAD_GET_CONTEXT, false, TID);&lt;br /&gt;
		if(!hThread)&lt;br /&gt;
		{	&lt;br /&gt;
			printf(&amp;quot;Error with OpenThread : %d\n&amp;quot;, GetLastError());&lt;br /&gt;
			goto cleanup;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		//met en pause le thread	&lt;br /&gt;
		SuspendThread(hThread);&lt;br /&gt;
	&lt;br /&gt;
		if(!GetThreadContext(hThread, &amp;amp;Context))&lt;br /&gt;
		{&lt;br /&gt;
			printf(&amp;quot;Error with GetThreadContext : %d\n&amp;quot;, GetLastError());&lt;br /&gt;
			goto cleanup;&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
&amp;nbsp;&amp;nbsp;		StackFrame.AddrPC.Offset=Context.Eip;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;		StackFrame.AddrPC.Mode=AddrModeFlat;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;		StackFrame.AddrFrame.Offset=Context.Ebp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;		StackFrame.AddrFrame.Mode=AddrModeFlat;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;		StackFrame.AddrStack.Offset=Context.Esp;&lt;br /&gt;
 		StackFrame.AddrStack.Mode=AddrModeFlat;&lt;br /&gt;
	&lt;br /&gt;
		StackFrame.AddrReturn.Mode=AddrModeFlat;&lt;br /&gt;
		&lt;br /&gt;
		/*&lt;br /&gt;
		printf(&amp;quot;Eip : 0x%x\n&amp;quot;, Context.Eip);&lt;br /&gt;
		printf(&amp;quot;Esp : 0x%x\n&amp;quot;, Context.Esp);&lt;br /&gt;
		printf(&amp;quot;Ebp : 0x%x\n&amp;quot;, Context.Ebp);&lt;br /&gt;
		*/&lt;br /&gt;
		&lt;br /&gt;
		//parcourt la pile&lt;br /&gt;
		do&lt;br /&gt;
		{	&lt;br /&gt;
			//printf(&amp;quot;AddrReturn : 0x%x\n&amp;quot;, StackFrame.AddrReturn.Offset);		&lt;br /&gt;
		&lt;br /&gt;
			//va fouiller la stack &lt;br /&gt;
			if(!StackWalk64(IMAGE_FILE_MACHINE_I386,&lt;br /&gt;
							hProcess,&lt;br /&gt;
							hThread,&lt;br /&gt;
							&amp;amp;StackFrame,&lt;br /&gt;
							&amp;amp;Context,&lt;br /&gt;
							NULL,&lt;br /&gt;
							SymFunctionTableAccess64,&lt;br /&gt;
							SymGetModuleBase64,&lt;br /&gt;
							NULL))&lt;br /&gt;
			{&lt;br /&gt;
				// Note that StackWalk64 generally does not set the last error code.&lt;br /&gt;
				printf(&amp;quot;Error with StackWalk&amp;quot;);&lt;br /&gt;
				//return 0;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			if(SymFromAddr(hProcess, (DWORD)StackFrame.AddrReturn.Offset, &amp;amp;Displacement, pSI))&lt;br /&gt;
			{&lt;br /&gt;
				if(SymGetModuleInfo64(hProcess, pSI-&amp;gt;ModBase, &amp;amp;IM))&lt;br /&gt;
					printf(&amp;quot;0x%x : %s!%s+0x%x\n&amp;quot;,(DWORD)pSI-&amp;gt;Address, IM.ModuleName, pSI-&amp;gt;Name, Displacement);&lt;br /&gt;
			}&lt;br /&gt;
			//else&lt;br /&gt;
				//printf(&amp;quot;Error with SymFromAddr : %d\n&amp;quot;, GetLastError());	&lt;br /&gt;
					&lt;br /&gt;
		}while(StackFrame.AddrReturn.Offset!=0);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		//relance le thread&lt;br /&gt;
		ResumeThread(hThread);&lt;br /&gt;
		&lt;br /&gt;
		CloseHandle(hThread);&lt;br /&gt;
		&lt;br /&gt;
		Thread32Next(hThreadSnap,&amp;amp;Th32);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	cleanup:&lt;br /&gt;
		&lt;br /&gt;
	if(hProcess)&lt;br /&gt;
		CloseHandle(hProcess);&lt;br /&gt;
	&lt;br /&gt;
	SymCleanup(hProcess);&lt;br /&gt;
&lt;br /&gt;
	return 0;	&lt;br /&gt;
}&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
------------CUT HERE--------------------&lt;br /&gt;
&lt;br /&gt;
A l'utilisation ca donne :&lt;br /&gt;
C:\ProgHack\c&amp;gt;StackWatcher cmd.exe&lt;br /&gt;
&lt;br /&gt;
Thread ID : 392&lt;br /&gt;
0x7c91e9b4 : ntdll!ZwWaitForSingleObject+0xc&lt;br /&gt;
0x7c802540 : kernel32!WaitForSingleObjectEx+0xa8&lt;br /&gt;
0x7c802520 : kernel32!WaitForSingleObject+0x12&lt;br /&gt;
0x4ad02cf4 : CMD!WaitProc+0x18&lt;br /&gt;
0x4ad02ff8 : CMD!ExecPgm+0x3fa&lt;br /&gt;
0x4ad02d42 : CMD!ECWork+0x84&lt;br /&gt;
0x4ad02dcb : CMD!ExtCom+0x40&lt;br /&gt;
0x4ad0145d : CMD!FindFixAndRun+0xcf&lt;br /&gt;
0x4ad01375 : CMD!Dispatch+0x137&lt;br /&gt;
0x4ad03ff1 : CMD!main+0x216&lt;br /&gt;
0x4ad05056 : CMD!mainCRTStartup+0x125&lt;br /&gt;
0x7c816fb4 : kernel32!BaseProcessStart+0x23&lt;br /&gt;
&lt;br /&gt;
Impressive n'est-il pas ? :}&lt;br /&gt;
L'int&eacute;ret ca peut &ecirc;tre de savoir par ou est pass&eacute; un code pour &eacute;xecut&eacute; une &lt;br /&gt;
action. Dans l'exemple suivant j'ai mit un BP sur l'API native ZwCreateProcessEx &lt;br /&gt;
qui vous vous en doutez sert a cr&eacute;e &agrave; process, je l'ai mit dans explorer.exe, &lt;br /&gt;
donc quand je vais lancer un process le programme va &ecirc;tre stop&eacute; par le &lt;br /&gt;
breakpoint et si on lance StackWatcher on peut voir :&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
[...]&lt;br /&gt;
Breakpoint sur	ZwCreateProcessEx de ntdll.dll l'api native qui call le noyau &lt;br /&gt;
pour lancer un process&lt;br /&gt;
Thread ID : 2008&lt;br /&gt;
0x7c819513 : kernel32!CreateProcessInternalW+0x1327&lt;br /&gt;
0x7c802332 : kernel32!CreateProcessW+0x2c&lt;br /&gt;
0x7ca11f93 : SHELL32!_SHCreateProcess+0x387&lt;br /&gt;
0x7ca11e7a : SHELL32!CShellExecute::_DoExecCommand+0xb4&lt;br /&gt;
0x7ca11e21 : SHELL32!CShellExecute::_TryInvokeApplication+0x49&lt;br /&gt;
0x7ca118b9 : SHELL32!CShellExecute::ExecuteNormal+0xb1&lt;br /&gt;
0x7ca11866 : SHELL32!ShellExecuteNormal+0x30&lt;br /&gt;
0x7ca117cb : SHELL32!ShellExecuteExW+0x8d&lt;br /&gt;
0x7ca1e4e4 : SHELL32!_InvokePidl+0x9f&lt;br /&gt;
0x7ca1e421 : SHELL32!CShellExecMenu::_InvokeOne+0xa0&lt;br /&gt;
0x7ca1e347 : SHELL32!CShellExecMenu::InvokeCommand+0xa7&lt;br /&gt;
0x7ca1e2ad : SHELL32!HDXA_LetHandlerProcessCommandEx+0xa5&lt;br /&gt;
0x7ca1e1b5 : SHELL32!CDefFolderMenu::InvokeCommand+0x17f&lt;br /&gt;
0x7ca300b2 : SHELL32!CShellLink::TargetContextMenu::InvokeCommand+0x22&lt;br /&gt;
0x7ca2fe91 : SHELL32!CShellLink::_InvokeCommandAsync+0x337&lt;br /&gt;
0x7ca2fe57 : SHELL32!CShellLink::InvokeCommand+0x259&lt;br /&gt;
0x7ca1e2ad : SHELL32!HDXA_LetHandlerProcessCommandEx+0xa5&lt;br /&gt;
0x7ca1e1b5 : SHELL32!CDefFolderMenu::InvokeCommand+0x17f&lt;br /&gt;
0x77f98355 : SHLWAPI!SHInvokeCommandsOnContextMenu+0x174&lt;br /&gt;
0x77f9926d : SHLWAPI!SHInvokeCommand+0x63&lt;br /&gt;
0x77f9932d : SHLWAPI!SHInvokeDefaultCommand+0x15&lt;br /&gt;
0x102c9a0 : explorer!CStartMenuHost::ExecItem+0x17&lt;br /&gt;
0x7cb6d9d7 : SHELL32!CStartMenuCallback::_ExecItem+0x17&lt;br /&gt;
0x7cb6f32e : SHELL32!CStartMenuCallback::CallbackSM+0xe0&lt;br /&gt;
0x7ca23edd : SHELL32!CMenuSFToolbar::CallCB+0xd9&lt;br /&gt;
0x7cba7520 : SHELL32!CMenuSFToolbar::v_ExecItem+0x8e&lt;br /&gt;
0x7cba40bf : SHELL32!CMenuToolbarBase::_DropDownOrExec+0xa6&lt;br /&gt;
0x7ca24a04 : SHELL32!CMenuToolbarBase::_OnNotify+0x2bf&lt;br /&gt;
0x7ca24401 : SHELL32!CMenuSFToolbar::_OnNotify+0x109&lt;br /&gt;
0x7ca2439a : SHELL32!CMenuToolbarBase::OnWinEvent+0x60&lt;br /&gt;
0x7ca2435a : SHELL32!CMenuSFToolbar::OnWinEvent+0x6b&lt;br /&gt;
0x7ca2428f : SHELL32!CMenuBand::OnWinEvent+0x1f8&lt;br /&gt;
0x7ca24159 : SHELL32!CMenuSite::v_WndProc+0xd9&lt;br /&gt;
0x7ca30e35 : SHELL32!CImpWndProc::s_WndProc+0x65&lt;br /&gt;
0x77d1870c : USER32!InternalCallWinProc+0x28&lt;br /&gt;
0x77d1875f : USER32!UserCallWinProcCheckWow+0x150&lt;br /&gt;
0x77d1b7d3 : USER32!SendMessageWorker+0x4a5&lt;br /&gt;
0x77d1b8ba : USER32!SendMessageW+0x7f&lt;br /&gt;
0x773aa3d1 : comctl32!CCSendNotify+0xc20&lt;br /&gt;
0x773ff831 : comctl32!TBSendUpClick+0x5f&lt;br /&gt;
0x77404778 : comctl32!TBOnLButtonUp+0x13b&lt;br /&gt;
0x77404bdb : comctl32!ToolbarWndProc+0xb30&lt;br /&gt;
0x77d1870c : USER32!InternalCallWinProc+0x28&lt;br /&gt;
0x77d1875f : USER32!UserCallWinProcCheckWow+0x150&lt;br /&gt;
0x77d1c5ee : USER32!CallWindowProcAorW+0x98&lt;br /&gt;
0x77d1c64a : USER32!CallWindowProcW+0x1b&lt;br /&gt;
0x773a1b3d : comctl32!CallOriginalWndProc+0x1a&lt;br /&gt;
0x773a1e6e : comctl32!CallNextSubclassProc+0x3c&lt;br /&gt;
0x773a2026 : comctl32!DefSubclassProc+0x46&lt;br /&gt;
0x7ca0ef96 : SHELL32!CSFToolbar::_DefWindowProc+0xb8&lt;br /&gt;
0x7ca0ef46 : SHELL32!CNotifySubclassWndProc::_SubclassWndProc+0x7d&lt;br /&gt;
0x773a1e6e : comctl32!CallNextSubclassProc+0x3c&lt;br /&gt;
0x773a207b : comctl32!MasterSubclassProc+0x54&lt;br /&gt;
0x77d1870c : USER32!InternalCallWinProc+0x28&lt;br /&gt;
0x77d1875f : USER32!UserCallWinProcCheckWow+0x150&lt;br /&gt;
0x77d188f1 : USER32!DispatchMessageWorker+0x306&lt;br /&gt;
0x77d18a01 : USER32!DispatchMessageW+0xf&lt;br /&gt;
0x100199d : explorer!CTray::_MessageLoop+0xd9&lt;br /&gt;
0x1011e62 : explorer!CTray::MainThreadProc+0x29&lt;br /&gt;
0x77f5422b : SHLWAPI!WrapperThreadProc+0x94&lt;br /&gt;
0x7c80b64c : kernel32!BaseThreadStart+0x37&lt;br /&gt;
&lt;br /&gt;
Thread Id : XXX&lt;br /&gt;
[...]&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Ouf ca fait de la peur :]&lt;br /&gt;
En tout cas je pense qu'il y moyen de bien s'amuser avec ce tools on peut &lt;br /&gt;
apprendre de bonne chose sur le fonctionnement de certains binaire system. Par &lt;br /&gt;
contre mieux vaut avoir les symbols pour ceux-ci si vous voulez des r&eacute;sultats &lt;br /&gt;
probants.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin en reversant Process Explorer j'ai remarqu&eacute; que le mofo utilisait un &lt;br /&gt;
driver afin de lire aussi la pile d'appel du thread dans le noyau, je suis &lt;br /&gt;
en train de continuer le combat afin que mon code le fasse aussi. Il m'a fallut &lt;br /&gt;
reverser le binaire, dumper le driver, reverse le driver ...Bref ca ma bien &lt;br /&gt;
prit la tete pour capter le bordel. Je suis en train de recoder un tool qui &lt;br /&gt;
reprend son fonctionnement&amp;nbsp;&amp;nbsp;mais code est over crade, avec des bouts d'asm &lt;br /&gt;
partout et du DeviceIoControl() &agrave; la pelle donc celui la ca m'etonnerais que je le montre :] &lt;br /&gt;
&lt;br /&gt;
En attendant vous avez de quoi vous amuser. Je vous file un .rar avec le binaire &lt;br /&gt;
les sources et les dll requises, enjoy !&lt;br /&gt;
&lt;br /&gt;
http://membres.lycos.fr/moi118118/StackWatcher.rar&lt;br /&gt;
&lt;br /&gt;
Ivanlef0u &lt;br /&gt;
&amp;quot;je te fist comme ca, comme ca et comme ca !&amp;quot;</description>
                    </item>
            </channel>
</rss>
