<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Pierre Noguès &#187; Reverse</title>
	<atom:link href="http://www.indahax.com/category/reverse/feed" rel="self" type="application/rss+xml" />
	<link>http://www.indahax.com</link>
	<description>Consultant en sécurité informatique</description>
	<lastBuildDate>Wed, 31 Mar 2010 12:35:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Introduction au Structured Exception Handler</title>
		<link>http://www.indahax.com/reverse/structured-exception-handler</link>
		<comments>http://www.indahax.com/reverse/structured-exception-handler#comments</comments>
		<pubDate>Thu, 19 Nov 2009 15:38:44 +0000</pubDate>
		<dc:creator>Pierre</dc:creator>
				<category><![CDATA[Reverse]]></category>
		<category><![CDATA[buffer overflow]]></category>
		<category><![CDATA[programmation]]></category>
		<category><![CDATA[seh]]></category>
		<category><![CDATA[structured exception handler]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://www.indahax.com/?p=5</guid>
		<description><![CDATA[Bon, c&#8217;est un veil article que j&#8217;avais écrit lorsque j&#8217;étudiais les buffer overflow sous Windows, il devait traiter des structured exception handler, de leur exploitation dans les débordements de tampon et les nouvelles protections mises au niveau du compilateur (Safe SEH). Je devais finir cet article un jour, mais je pense que ce jour n&#8217;arrivera [...]]]></description>
			<content:encoded><![CDATA[<p>Bon, c&#8217;est un veil article que j&#8217;avais écrit lorsque j&#8217;étudiais les <strong>buffer overflow</strong> sous Windows, il devait traiter des <strong>structured exception handler</strong>, de leur exploitation dans les <strong>débordements de tampon</strong> et les nouvelles protections mises au niveau du compilateur (Safe SEH). Je devais finir cet article un jour, mais je pense que ce jour n&#8217;arrivera jamais, alors je vais déjà lâcher cette <strong>introduction au SEH</strong> qui aidera peut être un pauvre internaute perdu sur Google. Attention ça peut donner mal au crane.</p>
<p><span id="more-5"></span></p>
<ol>
<li><span style="text-decoration: underline;"><strong>C&#8217;est quoi un SEH ?</strong></span></li>
</ol>
<p>C&#8217;est un gestionnaire d&#8217;exception qui permet au programmeur de gérer une exception lui même plutôt que de laisser le programme le faire (ce qui aboutit généralement à un ExitProcess() ). Concrètement ils sont représentés en C par les instructions __try / __except / __finally. Parmi les exceptions on peut distinguer :</p>
<ul>
<li><strong>Les exceptions materielles</strong> : typiquement un <em>ACCESS_VIOLATION</em> ou <em>DIVISION_BY_ZERO</em>, c&#8217;est le style d&#8217;exception que l&#8217;on rencontre le plus souvent.</li>
<li><strong>Les exceptions logicielles</strong> : c&#8217;est le programmeur lui même qui créé ce type d&#8217;exception, il les déclenche à l&#8217;aide d&#8217;une fonction <a href="http://msdn.microsoft.com/en-us/library/het71c37(VS.80).aspx" target="_blank">RaiseException()</a> . Un programmeur peut par exemple créer une exception NOT_ENOUGH_MEMORY lorsqu&#8217;il n&#8217;arrive plus à allouer de mémoire.</li>
</ul>
<p>Un SEH est responsable d&#8217;une portion de code sur laquelle il peut intercepter des exceptions. Dans cette section de code il peut également y avoir d&#8217;autre SEH qui gère eux aussi d&#8217;autre portion de code.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">SEH1[
  //code protégé par SEH1
  SEH2[
    //code protégé par SEH2, SEH1
    SEH3[
      ...
    ]
  ]
]</pre></div></div>

<p>Donc dans un programme on a pas un SEH mais plusieurs, et à différent niveau, lorsqu&#8217;un SEH ne gère pas une exception il la passe au SEH du niveau supérieur. En mémoire ils sont représentés sous forme d&#8217;une liste chainée dans la pile (on verra çà plus en détail après).</p>
<p><strong>Que se passe-t-il lorsqu&#8217;une exception est déclenchée ?</strong></p>
<p>Le système va passer en mode noyau, il va effectuer quelques opérations notamment un dump des  registres du processeur ( le contexte ) qu&#8217;il va placer sur la pile du thread. Il repasse ensuite en mode utilisateur dans la fonction <a href="http://www.nynaeve.net/?p=201">KiUserExceptionDispatcher()</a> de ntdll.dll.</p>
<p>Si le processus est en cours de débgage le programme va passer la main au débuggeur qui va lui même gérer l&#8217;exception. S&#8217;il n&#8217;y a pas de débuggeur, ou qu&#8217;il ne gère pas l&#8217;erreur, l&#8217;exception va être retransmise au premier SEH, c&#8217;est à dire celui qui est le plus proche de là où a été générée l&#8217;exception. Ce gestionnaire va alors regarder s&#8217;il est capable de gérer l&#8217;exception :</p>
<ul>
<li>S&#8217;il en est capable, le SEH fait alors son traitement, par exemple il peut essayer d&#8217;obtenir des informations sur la cause de l&#8217;erreur pour générer des informations utiles au débuggage, ou bien il peut choisir d&#8217;essayer de corriger l&#8217;erreur par modification de variable, des registres&#8230; Dans tous les cas il pourra choisir de reprendre l&#8217;exécution là où l&#8217;erreur à eu lieu ou bien après la portion de code qu&#8217;il protège.</li>
<li>S&#8217;il n&#8217;est pas capable de la gérer il la passe alors au SEH du niveau du dessus et ainsi de suite jusqu&#8217;à atteindre le dernier SEH.</li>
</ul>
<p>Le comportement du dernier SEH peut dépendre des logiciels que vous avez installés sous Windows, mais sur un Windows par défaut, il va créer une boite de dialogue avec quelques informations sur l&#8217;état des registres et faire un appel à ExitProcess() pour quitter l&#8217;application. Si vous avez installé un debuggeur, Windows vous proposera de lancer le débuggeur Just In Time&#8230;</p>
<ol>
<li><strong><span style="text-decoration: underline;">Au niveau assembleur</span></strong></li>
</ol>
<p>Les SEH sont stockés dans la pile sous forme d&#8217;une liste chainée. La structure d&#8217;un SEH est de la forme :</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">_EXCEPTION_REGISTRATION struc
     prev    dd      ?
     handler dd      ?
 _EXCEPTION_REGISTRATION ends</pre></div></div>

<p><em>prev</em> représente un pointeur sur le précédent SEH et <em>handler</em> est un pointeur vers la fonction qui va être appelée lorsqu&#8217;une exception sera levé.</p>
<p>Le début de cette liste chainée est stocké dans la TEB (Thread Environnement Block) dans le registre de segment fs en fs:[0]. Cela signifie également qu&#8217;une liste de SEH est propre à un thread et non à un processus.</p>
<p><img title="SEH en mémoire" src="images/seh1.JPG" alt="Les SEH en mémoire" /></p>
<p>fs:[0] pointe toujours vers le dernier SEH installé,c&#8217;est le premier qui sera appelé en cas d&#8217;exception.</p>
<p>Le premier SEH installé est différencié des autres par son pointeur prev qui a la valeur 0xFFFFFFFF, il est mis en place à la création du processus (dans BaseProcessStart ) et avant l&#8217;entrée dans le main()/WinMain() . Si une exception est déclenchée et qu&#8217;aucun SEH n&#8217;a géré cette exception, alors ce dernier SEH va appeler la fonction UnhandledExceptionFilter() . C&#8217;est cette fonction qui créé la boite de dialogue avec les infos sur les registres ou qui propose de lancer le debugeur en dernier recours (Le fameux Just In Time Debugging ) . Il est possible de modifier le comportement de ce seh en appelant la fonction <a href="http://msdn.microsoft.com/en-us/library/ms680634(VS.85).aspx">SetUnhandledExceptionFilter()</a> .</p>
<p>Pour mettre en place un SEH en assembleur on peut procéder de cette manière :</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">; adresse du handler</span>
<span style="color: #00007f; font-weight: bold;">push</span> handler
<span style="color: #666666; font-style: italic;">; adresse de la structure SEH précédente</span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">fs</span><span style="color: #339933;">:</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span>
<span style="color: #666666; font-style: italic;">; fait pointer fs:[0] vers notre nouveau SEH</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">fs</span><span style="color: #339933;">:</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span><span style="color: #00007f;">esp</span>
<span style="color: #666666; font-style: italic;">; ici le code protégé par le seh</span>
<span style="color: #666666; font-style: italic;">; ...</span>
&nbsp;
<span style="color: #666666; font-style: italic;">;on enléve le SEH</span>
<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">fs</span><span style="color: #339933;">:</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">esp</span><span style="color: #339933;">,</span><span style="color: #0000ff;">4</span>
<span style="color: #00007f; font-weight: bold;">ret</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; notre handler</span>
handler<span style="color: #339933;">:</span>
<span style="color: #666666; font-style: italic;">; ...</span></pre></div></div>

<p><strong> Une fois dans le handler </strong><br />
Lorsque le handler d&#8217;un SEH est appelé, des informations concernant l&#8217;exception sont mis en place sur la pile :</p>
<table border="0">
<tbody>
<tr>
<td>ESP + 0&#215;4</td>
<td><a href="http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx">EXCEPTION_RECORD</a></td>
</tr>
<tr>
<td>ESP + 0&#215;8</td>
<td>Le SEH</td>
</tr>
<tr>
<td>ESP + 0xC</td>
<td>CONTEXT (cf WinNT.h)</td>
</tr>
</tbody>
</table>
<p>La structure <em>EXCEPTION_RECORD</em> contient des informations sur l&#8217;exception comme :</p>
<ul>
<li>Le code de l&#8217;exception (ACCESS_VIOLATION, etc.)</li>
<li>Les flags : par exemple ils permettent de savoir si c&#8217;est une exception non continuable, si on est dans l&#8217;appel du stack unwinding (2éme appel du handler cf après)&#8230;</li>
<li>L&#8217;adresse où a eu lieu l&#8217;exception.</li>
</ul>
<p>C&#8217;est à partir de cette structure que le handler va pouvoir déterminer s&#8217;il a la capacité de gérer une exception.</p>
<p>La structure <em>CONTEXT</em> permet d&#8217;avoir des informations sur l&#8217;état des registres lorsque l&#8217;exception a eu lieu, c&#8217;est cette structure qu&#8217;il faut modifier si on veut reprendre l&#8217;exécution à un autre endroit en modifiant EIP.</p>
<p>Et enfin un pointeur vers le SEH que l&#8217;on avait mis sur la pile pour garder la portion de code où a eu lieu l&#8217;exception. Le fait d&#8217;avoir un pointeur vers ce SEH signifie que l&#8217;on peut construire un SEH personnalisé afin d&#8217;y intégrer des informations supplémentaires. Par exemple, on pourrait avoir besoin d&#8217;avoir une adresse pour reprendre l&#8217;exécution à un endroit sûre. Voici un exemple de code qui exploite ce système de SEH étendue :</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #0000ff;">.386</span>                      <span style="color: #666666; font-style: italic;">; force 32 bit code</span>
<span style="color: #000000; font-weight: bold;">.model</span> <span style="color: #000000; font-weight: bold;">flat</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">stdcall</span>      <span style="color: #666666; font-style: italic;">; memory model &amp;amp; calling convention</span>
<span style="color: #000000; font-weight: bold;">option</span> <span style="color: #000000; font-weight: bold;">casemap</span> <span style="color: #339933;">:</span><span style="color: #000000; font-weight: bold;">none</span>      <span style="color: #666666; font-style: italic;">; case sensitive</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">include</span> <span style="color: #000000; font-weight: bold;">c</span><span style="color: #339933;">:</span>\masm32\<span style="color: #000000; font-weight: bold;">include</span>\windows<span style="color: #339933;">.</span><span style="color: #00007f; font-weight: bold;">inc</span>
&nbsp;
MYSEH <span style="color: #000000; font-weight: bold;">STRUCT</span>
	prev		<span style="color: #000000; font-weight: bold;">DWORD</span> ?
	handler	<span style="color: #000000; font-weight: bold;">DWORD</span> ?
	safeeip	<span style="color: #000000; font-weight: bold;">DWORD</span> ?
MYSEH <span style="color: #000000; font-weight: bold;">ENDS</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">.code</span>
start<span style="color: #339933;">:</span>
&nbsp;
main <span style="color: #000000; font-weight: bold;">PROC</span>
<span style="color: #000000; font-weight: bold;">assume</span> <span style="color: #00007f;">fs</span><span style="color: #339933;">:</span><span style="color: #000000; font-weight: bold;">nothing</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; on mets en place un SEH étendu</span>
<span style="color: #00007f; font-weight: bold;">push</span> safeip			<span style="color: #666666; font-style: italic;">; notre champ supplémentaire safeeip</span>
<span style="color: #00007f; font-weight: bold;">push</span> handler		<span style="color: #666666; font-style: italic;">; le handler</span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">fs</span><span style="color: #339933;">:</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span>			<span style="color: #666666; font-style: italic;">; l'adresse du SEH suivant</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">fs</span><span style="color: #339933;">:</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span><span style="color: #00007f;">esp</span>		<span style="color: #666666; font-style: italic;">; on installe notre seh</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span><span style="color: #00007f;">eax</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">eax</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span><span style="color: #00007f;">eax</span>		<span style="color: #666666; font-style: italic;">; on génére un ACCESS_VIOLATION</span>
<span style="color: #00007f; font-weight: bold;">jmp</span> endx
&nbsp;
handler<span style="color: #339933;">:</span>
<span style="color: #666666; font-style: italic;">; esp == ret eip</span>
<span style="color: #666666; font-style: italic;">; esp + 0x04 == EXCEPTION_RECORD*</span>
<span style="color: #666666; font-style: italic;">; esp + 0x08 == MYSEH*</span>
<span style="color: #666666; font-style: italic;">; esp + 0x0C == CONTEXT</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; est ce un ACCESS_VIOLATION ?</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">esp</span><span style="color: #339933;">+</span><span style="color: #0000ff;">04h</span><span style="color: #009900; font-weight: bold;">&#93;</span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #009900; font-weight: bold;">&#40;</span>EXCEPTION_RECORD <span style="color: #000000; font-weight: bold;">PTR</span> <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">ebx</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">.</span>ExceptionCode<span style="color: #339933;">,</span> <span style="color: #0000ff;">0C0000005h</span>
<span style="color: #00007f; font-weight: bold;">jz</span> AViol
&nbsp;
<span style="color: #666666; font-style: italic;">; si ce n'est pas un ACCESS_VIOLATION on donne la main au handler suivant</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span>ExceptionContinueSearch
<span style="color: #00007f; font-weight: bold;">ret</span>
&nbsp;
AViol<span style="color: #339933;">:</span>
<span style="color: #666666; font-style: italic;">; si c'est un ACCESS_VIOLATION on reprend l'execution en myseh.safeeip</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">esp</span><span style="color: #339933;">+</span><span style="color: #0000ff;">08h</span><span style="color: #009900; font-weight: bold;">&#93;</span>	<span style="color: #666666; font-style: italic;">; ecx == MYSEH</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">esp</span><span style="color: #339933;">+</span><span style="color: #0000ff;">0Ch</span><span style="color: #009900; font-weight: bold;">&#93;</span>	<span style="color: #666666; font-style: italic;">; ebx == CONTEXT</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">edx</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">&#40;</span>MYSEH <span style="color: #000000; font-weight: bold;">PTR</span> <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">ebx</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">.</span>safeeip
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #009900; font-weight: bold;">&#40;</span>CONTEXT <span style="color: #000000; font-weight: bold;">PTR</span> <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">ecx</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">.</span>regEip<span style="color: #339933;">,</span> <span style="color: #00007f;">edx</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> ExceptionContinueExecution
<span style="color: #00007f; font-weight: bold;">ret</span>
&nbsp;
safeip<span style="color: #339933;">:</span>
endx<span style="color: #339933;">:</span>
<span style="color: #666666; font-style: italic;">; on enléve le SEH et restaure l'ancien</span>
<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">fs</span><span style="color: #339933;">:</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">esp</span><span style="color: #339933;">,</span><span style="color: #0000ff;">8</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">ret</span>
&nbsp;
main <span style="color: #000000; font-weight: bold;">endp</span>
<span style="color: #000000; font-weight: bold;">end</span> start</pre></div></div>

<p>Le compilateur windows utilise ce système de SEH étendue en réalisant une structure beaucoup plus complexe que le <em>EXCEPTION_REGISTRATION</em> vu au début.</p>
<p><strong> The stack unwinding </strong></p>
<p>En réalité le handler d&#8217;un SEH qui ne gère pas une exception doit être appelé une seconde fois. Ce deuxième appel est déclenché par le handler qui a décidé de gérer l&#8217;exception, il va reparcourir la liste des SEH depuis le début et exécuter une deuxième fois le handler de chaque SEH qui le précède, en rajoutant le flag <em>EH_UNWINDING</em> au niveau des Exceptions Flag de la structure <em>EXCEPTION_RECORD</em> pour que les handlers puissent différencier les 2 appels.</p>
<p>Ici l&#8217;action est bien déclenchée par le handler qui gère l&#8217;exception et non par le système, c&#8217;est à dire que c&#8217;est au programmeur d&#8217;implémenter cette fonctionnalité. Cela peut être fait en appelant la fonction <a href="http://msdn.microsoft.com/en-us/library/ms680609(VS.85).aspx">RtlUnwind()</a> (cf <a href="http://www.jorgon.freeserve.co.uk/Except/Except.htm#St">l&#8217;article</a> de J. Gorgon pour plus d&#8217;info ) .</p>
<p>Le rôle du stack unwinding est de nettoyer les variables de la portion de code qui a déclenché l&#8217;exception, par exemple c&#8217;est à ce moment qu&#8217;il est utile de fermer les handles, libérer la mémoire&#8230; Concrètement ce deuxième appel correspond au bloc __finaly en C.</p>
<p>De plus, si l&#8217;exécution reprend à partir d&#8217;un SEH de niveau supérieur, alors le stack unwinding est également responsable d&#8217;enlever de la liste des SEH tout ceux qui ont été mis après ce SEH (c&#8217;est à dire les SEH qui ne porte plus sur le code courant ).</p>
<p><br/><br />
Voilà c&#8217;est tout pour aujourd&#8217;hui, par la suite nous verrons comment sont implémentés les SEH dans les compilateurs, comment les exploiter lors d&#8217;un débordement de tampon et les nouvelles protéctions misent en place par Windows (Safe SEH).</p>
<p>Réferences :</p>
<p>http://www.microsoft.com/msj/0197/Exception/Exception.aspx</p>
<p>http://msdn.microsoft.com/en-us/library/swezty51(VS.80).aspx</p>
]]></content:encoded>
			<wfw:commentRss>http://www.indahax.com/reverse/structured-exception-handler/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
