~ubuntu-branches/ubuntu/precise/arj/precise-security

« back to all changes in this revision

Viewing changes to exe_sear.c

  • Committer: Bazaar Package Importer
  • Author(s): Guillem Jover
  • Date: 2004-06-27 08:07:09 UTC
  • Revision ID: james.westby@ubuntu.com-20040627080709-1gkxm72ex66gkwe4
Tags: upstream-3.10.21
ImportĀ upstreamĀ versionĀ 3.10.21

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: exe_sear.c,v 1.3 2003/10/16 10:32:46 andrew_belov Exp $
 
3
 * ---------------------------------------------------------------------------
 
4
 * Routines that fetch overlay data are located in this file.
 
5
 *
 
6
 */
 
7
 
 
8
#include "arj.h"
 
9
 
 
10
#ifdef ELF_EXECUTABLES
 
11
 #ifdef __QNXNTO__
 
12
    #include <libelf.h>
 
13
 #else
 
14
    #include <elf.h>
 
15
 #endif /* __QNXNTO__ */
 
16
#endif
 
17
 
 
18
DEBUGHDR(__FILE__)                      /* Debug information block */
 
19
 
 
20
/* ARJSFX module order */
 
21
 
 
22
#define MN_SFXJR                   1
 
23
#define MN_SFX                     2
 
24
#define MN_SFXV                    3
 
25
#define MN_SFXSTUB                 4
 
26
 
 
27
/* Define the ELF magic numbers if not defined yet */
 
28
 
 
29
#if defined(ELF_EXECUTABLES)&&!defined(ELFMAG)
 
30
 static char elfmag[4]={'E', 'L', 'F', 0x7F};
 
31
 #define ELFMAG elfmag
 
32
 #define SELFMAG 4
 
33
#endif
 
34
 
 
35
#if SFX_LEVEL>=ARJ
 
36
 
 
37
/* Local variables */
 
38
 
 
39
static char overlay_sig[]="RJ_SFX";
 
40
 
 
41
/* Looks for ARJ_SFX signature */
 
42
 
 
43
static void browse(FILE *stream)
 
44
{
 
45
 char buf[256];
 
46
 unsigned long cur_pos, sig_pos;
 
47
 int bytes_read;
 
48
 int i;
 
49
 char *buf_ptr;
 
50
 
 
51
 while(1)
 
52
 {
 
53
  cur_pos=ftell(stream);
 
54
  bytes_read=fread(buf, 1, sizeof(buf), stream);
 
55
  if(bytes_read<=0)
 
56
   error(M_CANTREAD);
 
57
  buf_ptr=buf;
 
58
  i=0;
 
59
  while(i<bytes_read)
 
60
  {
 
61
   if(*buf_ptr=='A'&&!strcmp(buf_ptr+1, overlay_sig))
 
62
   {
 
63
    sig_pos=cur_pos+(unsigned long)i;
 
64
    if(mget_dword(buf_ptr+8)==sig_pos)
 
65
     goto loc_hdr;
 
66
   }
 
67
   i++;
 
68
   buf_ptr++;
 
69
  }
 
70
  if(bytes_read==sizeof(buf))
 
71
   fseek(stream, -16L, SEEK_CUR);
 
72
 }
 
73
 loc_hdr:
 
74
 cur_pos+=(unsigned long)i+12L;
 
75
 fseek(stream, cur_pos, SEEK_SET);
 
76
}
 
77
 
 
78
/* Writes the contents of a FAR block to the output stream */
 
79
 
 
80
static void farblock_output(FILE *stream, char FAR *block, unsigned long len)
 
81
{
 
82
 #ifdef TILED
 
83
  while(len-->0)
 
84
  {
 
85
   if(fputc((int)*(block++), stream)==EOF)
 
86
    error(M_DISK_FULL);
 
87
  }
 
88
 #else
 
89
  file_write(block, 1, len, stream);
 
90
 #endif
 
91
}
 
92
 
 
93
#endif
 
94
 
 
95
/* Reads the EXE size from the header */
 
96
 
 
97
static unsigned long get_exe_size(FILE *stream)
 
98
{
 
99
 #if SFX_LEVEL>=ARJ
 
100
  unsigned long result=EXESIZE_ARJ;
 
101
 #elif SFX_LEVEL==ARJSFXV
 
102
  unsigned long result=EXESIZE_ARJSFXV;
 
103
 #else
 
104
  unsigned long result=EXESIZE_ARJSFX;
 
105
 #endif
 
106
 #ifndef ELF_EXECUTABLES
 
107
  unsigned int remainder, blocks;
 
108
 #else
 
109
  Elf32_Ehdr ehdr;
 
110
  Elf32_Shdr shdr;
 
111
  unsigned long ref_point;
 
112
  unsigned long cur_pos;
 
113
  unsigned int i;
 
114
 #endif
 
115
 
 
116
 #ifndef ELF_EXECUTABLES                /* Presume standard DOS or OS/2 EXE */
 
117
  fseek(stream, 2L, SEEK_SET);
 
118
  remainder=fget_word(stream);
 
119
  blocks=fget_word(stream);
 
120
  result=(unsigned long)(blocks-1)*512L+(unsigned long)remainder;
 
121
  return(result);
 
122
 #else                                  /* ELF (Linux, OS/2 PPC, Solaris...) */
 
123
  fread(&ehdr, 1, sizeof(ehdr), stream);
 
124
  if(memcmp(ehdr.e_ident, ELFMAG, SELFMAG))
 
125
   return(0);
 
126
  result=ehdr.e_shoff+(unsigned long)ehdr.e_shentsize*ehdr.e_shnum;
 
127
  fseek(stream, ehdr.e_shoff, SEEK_SET);
 
128
  for(i=0; i<ehdr.e_shnum; i++)
 
129
  {
 
130
   fseek(stream, ehdr.e_shoff+(unsigned long)i*ehdr.e_shentsize, SEEK_SET);
 
131
   cur_pos=ftell(stream);
 
132
   fread(&shdr, 1, sizeof(shdr), stream);
 
133
   ref_point=shdr.sh_offset+shdr.sh_size;
 
134
   /* Ignore uninitialized sections (BSS) */
 
135
   if(ref_point>result&&shdr.sh_type!=SHT_NOBITS)
 
136
    result=ref_point;
 
137
  }
 
138
  return(result);
 
139
 #endif
 
140
}
 
141
 
 
142
#if SFX_LEVEL>=ARJ
 
143
 
 
144
/* Performs all actions related to picking a block */
 
145
 
 
146
static void fetch_block(int num)
 
147
{
 
148
 FILE *stream;
 
149
 unsigned long exe_size;
 
150
 int t_num;
 
151
 unsigned long t_pos;
 
152
 char buf[256];
 
153
 int block_len;
 
154
 int bytes_read;
 
155
 unsigned int desc_word;
 
156
 
 
157
 stream=file_open_noarch(exe_name, m_rb);
 
158
 exe_size=get_exe_size(stream);
 
159
 fseek(stream, exe_size, SEEK_SET);
 
160
 t_pos=0L;
 
161
 for(t_num=0; t_num<num; t_num++)
 
162
 {
 
163
  fseek(stream, t_pos, SEEK_CUR);
 
164
  browse(stream);
 
165
  t_pos=fget_longword(stream);
 
166
 }
 
167
 crc32term=CRC_MASK;
 
168
 block_len=(int)min(sizeof(buf), t_pos);
 
169
 while(t_pos>0)
 
170
 {
 
171
  bytes_read=fread(buf, 1, block_len, stream);
 
172
  if(bytes_read<=0)
 
173
   break;
 
174
  crc32_for_block(buf, bytes_read);
 
175
  farblock_output(aostream, (char FAR *)buf, (unsigned long)bytes_read);
 
176
  t_pos-=(unsigned long)bytes_read;
 
177
  block_len=(int)min(sizeof(buf), t_pos);
 
178
 }
 
179
 fclose(stream);
 
180
 desc_word=SFXDESC_NONSFX;
 
181
 if(create_sfx==SFXCRT_SFX&&multivolume_option)
 
182
  desc_word=SFXDESC_SFXV;
 
183
 else if(create_sfx==SFXCRT_SFX)
 
184
  desc_word=SFXDESC_SFX;
 
185
 else if(create_sfx==SFXCRT_SFXJR)
 
186
  desc_word=SFXDESC_SFXJR;
 
187
 fput_word(desc_word, aostream);
 
188
 if(is_registered)
 
189
  desc_word=REG_ID;
 
190
 fput_word(desc_word, aostream);
 
191
 crc32term^=CRC_MASK;
 
192
 fput_dword(crc32term, aostream);
 
193
}
 
194
 
 
195
/* Picks the ARJSFX and stores ARJSFX run-time data */
 
196
 
 
197
void fetch_sfx()
 
198
{
 
199
 fetch_block(MN_SFX);
 
200
}
 
201
 
 
202
/* Picks the ARJSFXJR and stores ARJSFXJR run-time data */
 
203
 
 
204
void fetch_sfxjr()
 
205
{
 
206
 fetch_block(MN_SFXJR);
 
207
}
 
208
 
 
209
/* Picks the ARJSFXV and stores ARJSFXV run-time data */
 
210
 
 
211
void fetch_sfxv()
 
212
{
 
213
 fetch_block(MN_SFXV);
 
214
}
 
215
 
 
216
/* Picks the SFXSTUB */
 
217
 
 
218
void fetch_sfxstub()
 
219
{
 
220
 fetch_block(MN_SFXSTUB);
 
221
}
 
222
 
 
223
#endif
 
224
 
 
225
#if SFX_LEVEL<=ARJSFXV
 
226
 
 
227
/* SFX seek routine */
 
228
 
 
229
void sfx_seek()
 
230
{
 
231
 unsigned long exe_size;
 
232
 unsigned long fcrc;
 
233
 unsigned int block_size, bytes_read;
 
234
 char buf[256];
 
235
 
 
236
 exe_size=get_exe_size(aistream);
 
237
 fseek(aistream, exe_size, SEEK_SET);
 
238
 main_hdr_offset=find_header(0, aistream);
 
239
 fseek(aistream, -8L, SEEK_CUR);
 
240
 exe_size=ftell(aistream);
 
241
 reg_id=fget_word(aistream);            /* Descriptive word */
 
242
 reg_id=fget_word(aistream);
 
243
 fcrc=fget_longword(aistream);
 
244
 if(reg_id!=REG_ID)
 
245
  reg_id=0;
 
246
 fseek(aistream, 0L, SEEK_SET);
 
247
 crc32term=CRC_MASK;
 
248
 block_size=min((unsigned long)sizeof(buf), exe_size);
 
249
 while(exe_size>0L)
 
250
 {
 
251
  bytes_read=fread(buf, 1, block_size, aistream);
 
252
  if(bytes_read==0)
 
253
   break;
 
254
  crc32_for_block(buf, bytes_read);
 
255
  exe_size-=(unsigned long)bytes_read;
 
256
  block_size=min((unsigned long)block_size, exe_size);
 
257
 }
 
258
 if((crc32term^CRC_MASK)!=fcrc&&!skip_integrity_test)
 
259
  error(M_DAMAGED_SFX);
 
260
 fseek(aistream, main_hdr_offset, SEEK_SET);
 
261
}
 
262
 
 
263
#endif