RSS

(root)/ildjit/iljit-ecmasoft : 1 : src/iljit_ecmasoft_decoder.c

« back to all changes in this revision

Viewing changes to src/iljit_ecmasoft_decoder.c

Speziale Ettore
2009-11-18 11:12:35
Revision ID: ettore@mars-20091118111235-wsu25wqrt97661ql
Initial import into Bazaar.

Show diffs side-by-side

added added

removed removed

 
1
/*
 
2
 * Copyright (C) 2006  Campanoni Simone
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 */
 
18
/**
 
19
 * @file iljit_ecmasoft_decoder.c
 
20
 * 
 
21
 */
 
22
#include <stdio.h>
 
23
#include <assert.h>
 
24
#include <errno.h>
 
25
#include <string.h>
 
26
#include <stdlib.h>
 
27
#include <config.h>
 
28
 
 
29
// My header
 
30
#include <iljit_ecmasoft_decoder.h>
 
31
// End
 
32
 
 
33
/**
 
34
 *
 
35
 * Return the identificator of the assembly that this plugin can decodes
 
36
 */
 
37
static inline JITINT8 * get_ID_binary (void);
 
38
 
 
39
char * ecmasoft_getVersion(void);
 
40
char * ecmasoft_getName(void);
 
41
char * ecmasoft_getAuthor(void);
 
42
 
 
43
/**
 
44
 *
 
45
 * Decode the assembly referenced by the binary_info parameter
 
46
 */
 
47
static inline JITBOOLEAN decode_image (t_binary_information *binary_info);
 
48
 
 
49
/**
 
50
 *
 
51
 * Init the decoder
 
52
 */
 
53
static inline JITBOOLEAN decoder_init (t_binary_information *binary_info);
 
54
 
 
55
/**
 
56
 *
 
57
 * Shutdown the decoder
 
58
 */
 
59
static inline JITBOOLEAN decoder_shutdown (t_binary_information *info);
 
60
 
 
61
/**
 
62
 *
 
63
 * Decode the MS-DOS Header and stores the information in the binary_info struct
 
64
 */
 
65
static inline JITINT32 load_MSDOS_header (t_binary_information *binary_info);
 
66
 
 
67
/**
 
68
 *
 
69
 * Decode the MS-DOS Stub and stores the information in the binary_info struct
 
70
 */
 
71
static inline JITINT32 load_MSDOS_stub (t_binary_information *binary_info);
 
72
 
 
73
/**
 
74
 *
 
75
 * Decode the PE Header and stores the information in the binary_info struct
 
76
 */
 
77
static inline JITINT32 load_PE_header (t_binary_information *binary_info);
 
78
 
 
79
/**
 
80
 *
 
81
 * Decode the PE Optional Header and stores the information in the binary_info struct
 
82
 */
 
83
static inline JITINT32 load_PEOPTIONAL_header (t_binary_information *binary_info);
 
84
 
 
85
/**
 
86
 *
 
87
 * Decode the CLI Header and stores the information in the binary_info struct
 
88
 */
 
89
static inline JITINT32 load_CLI_header (t_binary_information *binary_info, JITUINT32 min_address);
 
90
 
 
91
/**
 
92
 *
 
93
 * Decode al the sections and stores the information in the binary_info struct
 
94
 */
 
95
static inline JITINT32 load_SECTIONS_header_table (t_binary_information *binary_info, JITUINT32 *min_address, JITUINT32 base);
 
96
 
 
97
/**
 
98
 *
 
99
 * Decode all the metadata and stores the information in the binary_info struct
 
100
 */
 
101
static inline JITINT32 load_metadata (t_binary_information *binary_info);
 
102
 
 
103
 
 
104
static inline JITINT32 load_assembly_references (t_binary_information *binary_info);
 
105
static inline void ecmasoft_compilationTime (char *buffer, JITINT32 bufferLength);
 
106
static inline void ecmasoft_compilationFlags (char *buffer, JITINT32 bufferLength);
 
107
 
 
108
t_plugin_interface plugin_interface={
 
109
        get_ID_binary                   ,
 
110
        decode_image                    ,
 
111
        decoder_shutdown                ,
 
112
        ecmasoft_getName                ,
 
113
        ecmasoft_getVersion             ,
 
114
        ecmasoft_getAuthor              ,
 
115
        ecmasoft_compilationFlags       ,
 
116
        ecmasoft_compilationTime
 
117
};
 
118
 
 
119
static inline JITINT8 * get_ID_binary (void){
 
120
        return (JITINT8 *)BINARY_ID;
 
121
}
 
122
 
 
123
static inline JITBOOLEAN decode_image (t_binary_information *binary_info){
 
124
        JITUINT32 min_address;
 
125
        JITUINT32 base;
 
126
        
 
127
        /* Assertions                   */
 
128
        assert(binary_info!=NULL);
 
129
 
 
130
        /* Decoder init                 */
 
131
        decoder_init(binary_info);
 
132
        
 
133
        /* Load MSDOS Header            */
 
134
        if (load_MSDOS_header (binary_info)!=0) {
 
135
                decoder_shutdown(binary_info);
 
136
                return -1;
 
137
        }
 
138
        base=binary_info->MSDOS_header.base;
 
139
        #ifdef DEBUG
 
140
        print_binary_offset(binary_info->binary);
 
141
        #endif
 
142
        
 
143
        /* Load MSDOS Stub              */
 
144
        if (load_MSDOS_stub (binary_info)!=0) {
 
145
                decoder_shutdown(binary_info);
 
146
                return -1;
 
147
        }
 
148
        #ifdef DEBUG
 
149
        print_binary_offset(binary_info->binary);
 
150
        #endif
 
151
 
 
152
        /* Load PE Header               */
 
153
        if (load_PE_header(binary_info)!=0){
 
154
                decoder_shutdown(binary_info);
 
155
                return -1;
 
156
        }
 
157
        #ifdef DEBUG
 
158
        print_binary_offset(binary_info->binary);
 
159
        #endif
 
160
        
 
161
        /* Load PE Optional Header      */
 
162
        if (binary_info->PE_info.optional_header_size!=0){
 
163
                if (load_PEOPTIONAL_header(binary_info)!=0){
 
164
                        decoder_shutdown(binary_info);
 
165
                        return -1;
 
166
                }
 
167
                #ifdef DEBUG
 
168
                print_binary_offset(binary_info->binary);
 
169
                #endif
 
170
        }
 
171
        
 
172
        /* Load all the sections        */
 
173
        if (load_SECTIONS_header_table (binary_info, &min_address, base)!=0){
 
174
                decoder_shutdown(binary_info);
 
175
                return -1;
 
176
        };
 
177
        #ifdef DEBUG
 
178
        print_binary_offset(binary_info->binary);
 
179
        #endif
 
180
 
 
181
        /* Load CLI Header              */
 
182
        if (load_CLI_header(binary_info, min_address)!=0){
 
183
                decoder_shutdown(binary_info);
 
184
                return -1;
 
185
        }
 
186
        #ifdef DEBUG
 
187
        print_binary_offset(binary_info->binary);
 
188
        #endif
 
189
        
 
190
        /* Load Metadata                */
 
191
        if (load_metadata(binary_info)!=0){
 
192
                decoder_shutdown(binary_info);
 
193
                return -1;
 
194
        }
 
195
        #ifdef DEBUG
 
196
        print_binary_offset(binary_info->binary);
 
197
        #endif
 
198
        
 
199
        /* Load assembly references     */
 
200
        if (load_assembly_references(binary_info)!=0){
 
201
                print_err("DECODER:             ERROR= Cannot load libraries. ", 0);
 
202
                decoder_shutdown(binary_info);
 
203
                return -1;
 
204
        }
 
205
                
 
206
        return 0;
 
207
}
 
208
 
 
209
static inline JITBOOLEAN decoder_init (t_binary_information *binary_info){
 
210
        if (sections_init(&(binary_info->sections))!=0) return -1;
 
211
        binary_info->binary.offset              = 0;
 
212
        binary_info->binary.relative_offset     = 0;//FIXME call the file_init
 
213
        //metadata_init(binary_info);
 
214
        return 0;
 
215
}
 
216
 
 
217
static inline JITBOOLEAN decoder_shutdown (t_binary_information *info){
 
218
        PDEBUG("DECODER: Decoder shutting down\n");
 
219
        assert(info!=NULL);
 
220
        sections_shutdown(&(info->sections));
 
221
        metadata_shutdown(&(info->metadata));
 
222
        PDEBUG("DECODER: Done\n");
 
223
        return 0;
 
224
}
 
225
 
 
226
 
 
227
 
 
228
 
 
229
 
 
230
 
 
231
 
 
232
 
 
233
/****************************************************************************************************************************
 
234
                                                SECOND LEVEL FUNCTIONS
 
235
****************************************************************************************************************************/
 
236
static inline JITINT32 load_MSDOS_header (t_binary_information *binary_info){
 
237
        JITINT8         buffer[DIM_BUF];
 
238
 
 
239
        /*      Assertion       */
 
240
        assert(binary_info!=NULL);
 
241
        assert(binary_info->binary.file!=NULL);
 
242
                        
 
243
        PDEBUG("DECODER: MS-DOS Header\n");
 
244
        if (il_read(buffer, 2, &(binary_info->binary))!=0) {
 
245
                PDEBUG("DECODER: ERROR= Cannot read the binary\n");
 
246
                print_err("ECMASOFT DECODER: load_MSDOS_header: ERROR = Error reading MSDOS header. ", 0);
 
247
                return -1;
 
248
        }
 
249
        if (buffer[0]!='M' || buffer[1]!='Z') {
 
250
                print_err("DECODER: ERROR= The MS-DOS header is not standard. ", 0);
 
251
                PDEBUG("DECODER:        Byte 0=%c\n", buffer[0]);
 
252
                PDEBUG("DECODER:        Byte 1=%c\n", buffer[1]);
 
253
                return -1;
 
254
        }
 
255
        if (il_read(buffer+2, 62, &(binary_info->binary))!=0) {
 
256
                print_err("ECMASOFT DECODER: load_MSDOS_header: ERROR = Error reading MSDOS header. ", 0);
 
257
                return -1;
 
258
        }
 
259
        binary_info->MSDOS_header.base = (*(JITUINT32 *)(buffer+60));
 
260
        if ((binary_info->MSDOS_header.base) < (binary_info->binary.offset)){
 
261
                print_err("DECODER: ERROR= The offset if grater than the base. ", 0);
 
262
                return -1;
 
263
        }
 
264
        #ifdef DEBUG
 
265
        print_binary_offset(binary_info->binary);
 
266
        #endif
 
267
        PDEBUG("DECODER:                base                            =       0x%X            %d\n", (JITUINT32)(binary_info->MSDOS_header.base), binary_info->MSDOS_header.base);
 
268
 
 
269
        return 0;
 
270
}
 
271
 
 
272
static inline JITINT32 load_MSDOS_stub (t_binary_information *binary_info){
 
273
        JITINT8         buffer[DIM_BUF];
 
274
        
 
275
        /*      Assertion       */
 
276
        assert(binary_info!=NULL);
 
277
        
 
278
        PDEBUG("DECODER: MS-DOS Stub\n");
 
279
        if (il_read(buffer, 64, &(binary_info->binary))!=0) {
 
280
                print_err("ECMASOFT DECODER: load_MSDOS_stub: ERROR = Error reading MSDOS stub. ", 0);
 
281
                return -1;
 
282
        }
 
283
        return 0;
 
284
}
 
285
 
 
286
static inline JITINT32 load_PE_header (t_binary_information *binary_info){
 
287
        JITINT8         buffer[DIM_BUF];
 
288
        
 
289
        /*      Assertion       */
 
290
        assert(binary_info!=NULL);
 
291
        
 
292
        PDEBUG("DECODER: PE File Header\n");
 
293
        if (il_read(buffer, 4, &(binary_info->binary))!=0) {
 
294
                print_err("ECMASOFT DECODER: load_PE_header: ERROR = Error reading PE header. ", 0);
 
295
                return -1;
 
296
        }
 
297
        if (buffer[0]!='P' || buffer[1]!='E' || buffer[2]!='\0' || buffer[3]!='\0') {
 
298
                PDEBUG("DECODER: ERROR= The binary hasn't the PE header standard\n");
 
299
                return -1;
 
300
        }
 
301
        if (il_read(buffer, 20, &(binary_info->binary))!=0) {
 
302
                print_err("ECMASOFT DECODER: load_PE_header: ERROR = Error reading PE header. ", 0);
 
303
                return -1;
 
304
        }
 
305
        binary_info->PE_info.section_cardinality        = (*(JITUINT16 *)(buffer+2));
 
306
        binary_info->PE_info.time_stamp                 = (*(JITUINT32 *)(buffer+4));
 
307
        binary_info->PE_info.optional_header_size       = (*(JITUINT16 *)(buffer+16));
 
308
        binary_info->PE_info.characteristic             = (*(JITUINT16 *)(buffer+18));
 
309
        binary_info->PE_info.isDLL                      = ( (*(JITUINT16 *)(buffer+18)) & 0x2000 ) != 0 ? 1 : 0;
 
310
        PDEBUG("DECODER:                Section cardinality             =       0x%X            %d\n", binary_info->PE_info.section_cardinality, binary_info->PE_info.section_cardinality);
 
311
        PDEBUG("DECODER:                Time stamp                      =       0x%X    %d\n", binary_info->PE_info.time_stamp, binary_info->PE_info.time_stamp);
 
312
        PDEBUG("DECODER:                Optional header size            =       0x%X            %d\n", binary_info->PE_info.optional_header_size, binary_info->PE_info.optional_header_size);
 
313
        PDEBUG("DECODER:                DLL flags                       =       0x%X            %d\n", (JITUINT32)binary_info->PE_info.isDLL, binary_info->PE_info.isDLL);
 
314
        PDEBUG("DECODER:        Check header value\n");
 
315
        if ((binary_info->PE_info.section_cardinality==0) || (binary_info->PE_info.optional_header_size!=0 && (binary_info->PE_info.optional_header_size < 216 || binary_info->PE_info.optional_header_size > 1024))){
 
316
                PDEBUG("DECODER: ERROR= The binary is not the CIL image\n");
 
317
                return -1;
 
318
        }
 
319
        PDEBUG("DECODER:                Optional header size OK\n");
 
320
        return 0;
 
321
}
 
322
 
 
323
static inline JITINT32 load_PEOPTIONAL_header (t_binary_information *binary_info){
 
324
        JITINT8 buffer[DIM_BUF];
 
325
        assert(binary_info!=NULL);
 
326
        
 
327
        PDEBUG("DECODER: PE Optional header\n");
 
328
        ////////////////////////////////        Standard fields
 
329
        PDEBUG("DECODER:        Standard fields\n");
 
330
        if (il_read(buffer, binary_info->PE_info.optional_header_size, &(binary_info->binary))!=0) {
 
331
                print_err("ECMASOFT DECODER: load_PEOPTIONAL_header: ERROR = Error reading PEOPTIONAL header. ", 0);
 
332
                return -1;
 
333
        }
 
334
        binary_info->PE_optional_header.standard_fields.code_size               = (*(unsigned short int *)(buffer+4));
 
335
        binary_info->PE_optional_header.standard_fields.size_initialized_data   = (*(unsigned int *)(buffer+8));
 
336
        binary_info->PE_optional_header.standard_fields.size_unitialized_data   = (*(unsigned int *)(buffer+12));
 
337
        binary_info->PE_optional_header.standard_fields.entry_point_address     = (*(unsigned int *)(buffer+16));
 
338
        binary_info->PE_optional_header.standard_fields.base_of_code            = (*(unsigned int *)(buffer+20));
 
339
        binary_info->PE_optional_header.standard_fields.base_of_data            = (*(unsigned int *)(buffer+24));
 
340
        PDEBUG("DECODER:                        Code size                       =       0x%X            %ld\n", binary_info->PE_optional_header.standard_fields.code_size, (unsigned long int)binary_info->PE_optional_header.standard_fields.code_size);
 
341
        PDEBUG("DECODER:                        Size initialized data           =       0x%X            %ld\n", binary_info->PE_optional_header.standard_fields.size_initialized_data, (long int)binary_info->PE_optional_header.standard_fields.size_initialized_data);
 
342
        PDEBUG("DECODER:                        Size unitialized data           =       0x%X            %ld\n", binary_info->PE_optional_header.standard_fields.size_unitialized_data, (long int)binary_info->PE_optional_header.standard_fields.size_unitialized_data);
 
343
        PDEBUG("DECODER:                        Entry point RVA                 =       0x%X            %ld\n", binary_info->PE_optional_header.standard_fields.entry_point_address, (long int)binary_info->PE_optional_header.standard_fields.entry_point_address);
 
344
        PDEBUG("DECODER:                        Code base RVA                   =       0x%X            %ld\n", binary_info->PE_optional_header.standard_fields.base_of_code, (long int)binary_info->PE_optional_header.standard_fields.base_of_code);
 
345
        PDEBUG("DECODER:                        Data base RVA                   =       0x%X            %ld\n", binary_info->PE_optional_header.standard_fields.base_of_data, (long int)binary_info->PE_optional_header.standard_fields.base_of_data);
 
346
 
 
347
        ////////////////////////////////        Windows NT specific
 
348
        PDEBUG("DECODER:        Windows NT specific fields\n");
 
349
        binary_info->PE_optional_header.NT_info.file_alignment                  = (*(unsigned int *)(buffer+36));
 
350
        binary_info->PE_optional_header.NT_info.image_size                      = (*(unsigned int *)(buffer+56));
 
351
        binary_info->PE_optional_header.NT_info.header_size                     = (*(unsigned int *)(buffer+60));
 
352
        binary_info->PE_optional_header.NT_info.subsystem                       = (*(unsigned short int *)(buffer+68));
 
353
        PDEBUG("DECODER:                        File alignment                  =       0x%X            %ld\n", binary_info->PE_optional_header.NT_info.file_alignment, (long int)binary_info->PE_optional_header.NT_info.file_alignment);
 
354
        PDEBUG("DECODER:                        Image size                      =       0x%X            %ld\n", binary_info->PE_optional_header.NT_info.image_size, (long int)binary_info->PE_optional_header.NT_info.image_size);
 
355
        PDEBUG("DECODER:                        Header size                     =       0x%X            %ld\n", binary_info->PE_optional_header.NT_info.header_size, (long int)binary_info->PE_optional_header.NT_info.header_size);
 
356
        PDEBUG("DECODER:                        SubSystem                       =       0x%X            %ld\n", binary_info->PE_optional_header.NT_info.subsystem, (long int)binary_info->PE_optional_header.NT_info.subsystem);
 
357
        PDEBUG("DECODER:                        Check values\n");
 
358
        if (binary_info->PE_optional_header.NT_info.file_alignment!=0x200 && binary_info->PE_optional_header.NT_info.file_alignment!=0x1000){
 
359
                print_err("DECODER:             ERROR= The file alignment is not 0x200 or 0x1000 as described in the ECMA 335 spectification. ", 0);
 
360
                return -1;
 
361
        }
 
362
        PDEBUG("DECODER:                        File alignment OK\n");
 
363
        PDEBUG("DECODER:                        Directories cardinality OK\n");
 
364
        
 
365
        /* Data directories             */
 
366
        PDEBUG("DECODER:        Data directories\n");
 
367
        binary_info->PE_optional_header.data_directories.import_table_RVA       = (*(unsigned int *)(buffer + 104));
 
368
        binary_info->PE_optional_header.data_directories.import_table_size      = (*(unsigned int *)(buffer + 108));
 
369
        binary_info->PE_optional_header.data_directories.relocation_table_RVA   = (*(unsigned int *)(buffer + 136));
 
370
        binary_info->PE_optional_header.data_directories.relocation_table_size  = (*(unsigned int *)(buffer + 140));
 
371
        binary_info->PE_optional_header.data_directories.import_address_table   = (*(unsigned long int *)(buffer + 192));
 
372
        binary_info->PE_optional_header.data_directories.cli_header_RVA         = (*(unsigned int *)(buffer + 208));
 
373
        binary_info->PE_optional_header.data_directories.cli_header_size        = (*(unsigned int *)(buffer + 212));
 
374
        PDEBUG("DECODER:                        Import table RVA        =       0x%X            %d\n",  binary_info->PE_optional_header.data_directories.import_table_RVA, binary_info->PE_optional_header.data_directories.import_table_RVA);
 
375
        PDEBUG("DECODER:                        Import table size       =       0x%X            %d\n",  binary_info->PE_optional_header.data_directories.import_table_size, binary_info->PE_optional_header.data_directories.import_table_size);
 
376
        PDEBUG("DECODER:                        Relocation table RVA    =       0x%X            %d\n",  binary_info->PE_optional_header.data_directories.relocation_table_RVA, binary_info->PE_optional_header.data_directories.relocation_table_RVA);
 
377
        PDEBUG("DECODER:                        Relocation table size   =       0x%X            %d\n",  binary_info->PE_optional_header.data_directories.relocation_table_size, binary_info->PE_optional_header.data_directories.relocation_table_size);
 
378
        PDEBUG("DECODER:                        Import address table    =       0x%X            %lld\n",        (unsigned int)binary_info->PE_optional_header.data_directories.import_address_table, binary_info->PE_optional_header.data_directories.import_address_table);
 
379
        PDEBUG("DECODER:                        CLI header RVA          =       0x%X            %d\n",  binary_info->PE_optional_header.data_directories.cli_header_RVA, binary_info->PE_optional_header.data_directories.cli_header_RVA);
 
380
        PDEBUG("DECODER:                        CLI header size         =       0x%X            %d\n",  binary_info->PE_optional_header.data_directories.cli_header_size, binary_info->PE_optional_header.data_directories.cli_header_size);
 
381
 
 
382
        /* Return                       */
 
383
        return 0;
 
384
}
 
385
 
 
386
static inline JITINT32 load_CLI_header (t_binary_information *binary_info, JITUINT32 min_address){
 
387
        JITINT8 buffer[DIM_BUF];
 
388
        JITUINT32 base;
 
389
 
 
390
        /*      Assertion       */
 
391
        assert(binary_info!=NULL);
 
392
        
 
393
        PDEBUG("DECODER:        Seeking to the CLI Header\n");
 
394
        
 
395
        // Seek to the beginning of the first section 
 
396
        PDEBUG("DECODER:                Seek to the begin of the first section\n");     
 
397
        if(seek_within_file(&(binary_info->binary), buffer, binary_info->binary.offset, min_address)!=0){
 
398
                print_err("DECODER:     ERROR= Cannot seek to the minimum address computed. ", 0);
 
399
                return -1;
 
400
        }
 
401
        assert(binary_info!=NULL);
 
402
        set_metadata_start_point(&(binary_info->binary), (binary_info->binary).offset);
 
403
        (binary_info->binary).relative_offset=0;
 
404
        #ifdef DEBUG
 
405
        print_binary_offset(binary_info->binary);
 
406
        #endif
 
407
        
 
408
        // Delete the delta between the begin of the file and the first section
 
409
        PDEBUG("DECODER:                Delete from all sections the delta between the begin of the file and the begin of the first section\n");        
 
410
        if (add_offset_to_real_address_for_sections(get_first_section(binary_info->sections), -min_address)!=0){
 
411
                print_err("DECODER:     ERROR= Cannot add offset to the real address for all section. ", 0);
 
412
                return -1;
 
413
        }
 
414
        
 
415
        // Compute the address of the file where is the CLI header from the first section
 
416
        PDEBUG("DECODER:                Compute the CLI header address whitin the file from the first section\n");
 
417
        base=convert_virtualaddress_to_realaddress (binary_info->sections, binary_info->PE_optional_header.data_directories.cli_header_RVA);
 
418
        PDEBUG("DECODER:                        CLI header address from the begin of the file           = 0x%X  %d\n", base, base);
 
419
        base-=min_address;
 
420
        PDEBUG("DECODER:                        CLI header address from the begin of the first section  = 0x%X  %d\n", base, base);
 
421
        #ifdef DEBUG
 
422
        print_binary_offset(binary_info->binary);
 
423
        #endif
 
424
 
 
425
        // Seek to the CLI header
 
426
        PDEBUG("DECODER:                Seek to the CLI header address\n");
 
427
        if(seek_within_file(&(binary_info->binary), buffer, 0, base)!=0){
 
428
                print_err("DECODER:     ERROR= Cannot seek to the cli header. ", 0);
 
429
                return -1;
 
430
        }
 
431
        #ifdef DEBUG
 
432
        print_binary_offset(binary_info->binary);
 
433
        #endif
 
434
        
 
435
        if (il_read(buffer, 72, &(binary_info->binary))!=0) {
 
436
                print_err("ECMASOFT DECODER: load_CLI_header: ERROR = Error reading CLI header. ", 0);
 
437
                return -1;
 
438
        }
 
439
        binary_info->cli_information.cb                         = (*(JITUINT32 *)(buffer));
 
440
        binary_info->cli_information.mayor_runtime_version      = (*(JITUINT16 *)(buffer+4));
 
441
        binary_info->cli_information.minor_runtime_version      = (*(JITUINT16 *)(buffer+6));
 
442
        binary_info->cli_information.metadata_RVA               = (*(JITUINT32 *)(buffer+8));
 
443
        binary_info->cli_information.metadata_size              = (*(JITUINT32 *)(buffer+12));
 
444
        binary_info->cli_information.flags                      = (*(JITUINT32 *)(buffer+16));
 
445
        binary_info->cli_information.entry_point_token          = (*(JITUINT32 *)(buffer+20));
 
446
        binary_info->cli_information.resources_RVA              = (*(JITUINT32 *)(buffer+24));
 
447
        binary_info->cli_information.resources_size             = (*(JITUINT32 *)(buffer+28));
 
448
        binary_info->cli_information.strong_name_signature      = (*(JITUINT32 *)(buffer+32));
 
449
        binary_info->cli_information.vtable_fixups              = (*(JITUINT32 *)(buffer+48));
 
450
        #ifdef PRINTDEBUG
 
451
        PDEBUG("DECODER:        CLI Header\n");
 
452
        PDEBUG("DECODER:                CB                              =       0x%X            %d\n",  binary_info->cli_information.cb, binary_info->cli_information.cb);
 
453
        PDEBUG("DECODER:                Mayor runtime version           =       0x%X            %d\n",  (JITUINT32)binary_info->cli_information.mayor_runtime_version, binary_info->cli_information.mayor_runtime_version);
 
454
        PDEBUG("DECODER:                Minor runtime version           =       0x%X            %d\n",  (JITUINT32)binary_info->cli_information.minor_runtime_version, binary_info->cli_information.minor_runtime_version);
 
455
        PDEBUG("DECODER:                Metadata RVA                    =       0x%X            %d\n",  binary_info->cli_information.metadata_RVA, binary_info->cli_information.metadata_RVA);
 
456
        PDEBUG("DECODER:                Metadata size                   =       0x%X            %d\n",  binary_info->cli_information.metadata_size, binary_info->cli_information.metadata_size);
 
457
                {
 
458
                char *temp_buffer=cli_flags_to_string(binary_info->cli_information.flags);
 
459
                PDEBUG("DECODER:                Flags                           =       0x%X            %d      %s\n",  binary_info->cli_information.flags, binary_info->cli_information.flags, temp_buffer);
 
460
                free (temp_buffer);
 
461
        }
 
462
        PDEBUG("DECODER:                Entry point token               =       0x%X    %d\n",  binary_info->cli_information.entry_point_token, binary_info->cli_information.entry_point_token);
 
463
        PDEBUG("DECODER:                Resources RVA                   =       0x%X            %d\n",  binary_info->cli_information.resources_RVA, binary_info->cli_information.resources_RVA);
 
464
        PDEBUG("DECODER:                Resources size                  =       0x%X            %d\n",  binary_info->cli_information.resources_size, binary_info->cli_information.resources_size);
 
465
        PDEBUG("DECODER:                Strong name signature           =       0x%X            %lld\n", (JITUINT32)binary_info->cli_information.strong_name_signature, binary_info->cli_information.strong_name_signature);
 
466
        PDEBUG("DECODER:                VTable fixups                   =       0x%X            %lld\n", (JITUINT32)binary_info->cli_information.vtable_fixups, binary_info->cli_information.vtable_fixups);
 
467
        print_binary_offset(binary_info->binary);
 
468
        #endif
 
469
 
 
470
        return 0;
 
471
}
 
472
 
 
473
static inline JITINT32 load_SECTIONS_header_table (t_binary_information *binary_info, JITUINT32 *min_address, JITUINT32 base){
 
474
        JITINT32 num_sections;
 
475
        JITINT32 is_cormeta;
 
476
        JITUINT32 max_address;
 
477
        JITUINT32 debug_rva;
 
478
        JITUINT32 debug_size;
 
479
        JITUINT32 data_rva;
 
480
        JITUINT32 data_size;
 
481
        JITUINT32 tls_rva;
 
482
        JITUINT32 tls_size;
 
483
        JITUINT32 rsrc_rva;
 
484
        JITUINT32 rsrc_size;
 
485
        JITINT8 buffer[DIM_BUF];
 
486
 
 
487
        /* Assertions           */
 
488
        assert(binary_info!=NULL);
 
489
        
 
490
        PDEBUG("DECODER: Section headers table\n");
 
491
        num_sections=binary_info->PE_info.section_cardinality;
 
492
        is_cormeta      = 0;
 
493
        max_address     = MIN_UINT;
 
494
        (*min_address)  = (JITUINT32)MAX_UINT;
 
495
        debug_rva       = 0;
 
496
        debug_size      = 0;
 
497
        data_rva        = 0;
 
498
        data_rva        = 0;
 
499
        tls_rva         = 0;
 
500
        tls_size        = 0;
 
501
        rsrc_size       = 0;
 
502
        rsrc_size       = 0;
 
503
        while (num_sections > 0){
 
504
                PDEBUG("DECODER:                Section %d\n", num_sections);
 
505
                t_section *current_section;
 
506
        
 
507
                if (il_read(buffer, 40, &(binary_info->binary))!=0) {
 
508
                        print_err("DECODER: ERROR during reading from file. ", 0);
 
509
                        return -1;
 
510
                }
 
511
                current_section=add_new_section(binary_info->sections);
 
512
                if (current_section==NULL) {
 
513
                        print_err("DECODER: ERROR= current_section is NULL. ", 0);
 
514
                        return -1;
 
515
                }
 
516
 
 
517
                // Read the section values
 
518
                strncpy(current_section->name, (char *)buffer, sizeof(char)*8);
 
519
                current_section->virtual_size           = *(JITUINT32 *)(buffer+8);
 
520
                current_section->virtual_address        = *(JITUINT32 *)(buffer+12);
 
521
                current_section->real_size              = *(JITUINT32 *)(buffer+16);
 
522
                current_section->real_address           = *(JITUINT32 *)(buffer+20);
 
523
                current_section->rva_relocation_pointer = *(JITUINT32 *)(buffer+24);
 
524
                current_section->rva_relocation_number  = *(JITUINT16 *)(buffer+32);
 
525
                current_section->characteristic         = *(JITUINT32 *)(buffer+36);
 
526
                
 
527
                // Print information read
 
528
                PDEBUG("DECODER:                        Name                    =       %s\n", current_section->name);
 
529
                PDEBUG("DECODER:                        Virtual size            =       0x%X    %d\n", current_section->virtual_size, current_section->virtual_size);
 
530
                PDEBUG("DECODER:                        Virtual address         =       0x%X    %d\n", current_section->virtual_address, current_section->virtual_address);
 
531
                PDEBUG("DECODER:                        Real size               =       0x%X    %d\n", current_section->real_size, current_section->real_size);
 
532
                PDEBUG("DECODER:                        Real address            =       0x%X    %d\n", current_section->real_address, current_section->real_address);
 
533
                PDEBUG("DECODER:                        RVA relocation pointer  =       0x%X    %d\n", current_section->rva_relocation_pointer, current_section->rva_relocation_pointer);
 
534
                PDEBUG("DECODER:                        RVA relocation number   =       0x%X    %d\n", current_section->rva_relocation_number, current_section->rva_relocation_number);
 
535
                        {
 
536
                        char *temp=section_characteristic_to_string(current_section->characteristic);
 
537
                        PDEBUG("DECODER:                        Characteristic          =       0x%X    %s\n", current_section->characteristic, temp);
 
538
                        free(temp);
 
539
                }
 
540
                PDEBUG("DECODER:                        Max address             =       0x%X    %d\n", max_address, max_address);
 
541
                PDEBUG("DECODER:                        Min address             =       0x%X    %d\n", *min_address, *min_address);
 
542
                #ifdef DEBUG
 
543
                print_binary_offset(binary_info->binary);
 
544
                #endif
 
545
 
 
546
                // Check some condition
 
547
                if (current_section->virtual_size > current_section->real_size){
 
548
                        PDEBUG("DECODER:                        Virtual size grater than the real one\n");
 
549
                        current_section->virtual_size=current_section->real_size;
 
550
                }
 
551
                else {
 
552
                        if (!current_section->virtual_size){
 
553
                                PDEBUG("DECODER:                        Virtual size is zero\n");
 
554
                                current_section->virtual_size=current_section->real_size;
 
555
                                if (!current_section->virtual_address){
 
556
                                        PDEBUG("DECODER:                        Virtual address is zero\n");
 
557
                                        current_section->virtual_address=current_section->real_address;
 
558
                                }
 
559
                        }
 
560
                }
 
561
 
 
562
                // Check values
 
563
                PDEBUG("DECODER:                        Check values\n");
 
564
                if (((current_section->virtual_address + current_section->virtual_size) & (JITUINT32)MAX_UINT) < current_section->virtual_address){
 
565
                        print_err("DECODER:             Virtual size is too big. ", 0);
 
566
                        return -1;
 
567
                }
 
568
                PDEBUG("DECODER:                                Virtual size OK\n");
 
569
                if (((current_section->real_address + current_section->real_size) & (JITUINT32)MAX_UINT) < current_section->real_address){
 
570
                        print_err("DECODER:             Real size is too big. ", 0);
 
571
                        return -1;
 
572
                }
 
573
                PDEBUG("DECODER:                                Real size OK\n");
 
574
                
 
575
                // Classify the current section
 
576
                if (!memcmp(buffer, DOTTEXT_SECTION, 8)){
 
577
                        PDEBUG("DECODER:                        Text section\n");
 
578
                        base=current_section->virtual_address;
 
579
                } else if (!memcmp(buffer, CORMETA_SECTION, 8)){
 
580
                        PDEBUG("DECODER:                        Cormeta section\n");
 
581
                        base=current_section->virtual_address;
 
582
                        is_cormeta=1;
 
583
                } else if (!memcmp(buffer, DEBUG_SECTION, 8)){
 
584
                        PDEBUG("DECODER:                        IL debug section\n");
 
585
                        debug_rva=current_section->virtual_address;
 
586
                        debug_size=current_section->virtual_size;
 
587
                } else if (!memcmp(buffer, SDATA_SECTION, 8)){
 
588
                        PDEBUG("DECODER:                        SData section\n");
 
589
                        data_rva=current_section->virtual_address;
 
590
                        data_size=current_section->virtual_size;
 
591
                } else if (!memcmp(buffer, DATA_SECTION, 8)){
 
592
                        PDEBUG("DECODER:                        Data section\n");
 
593
                        data_rva=current_section->virtual_address;
 
594
                        data_size=current_section->virtual_size;
 
595
                } else if (!memcmp(buffer, TLS_SECTION, 8)){
 
596
                        PDEBUG("DECODER:                        TLS section\n");
 
597
                        tls_rva=current_section->virtual_address;
 
598
                        tls_size=current_section->virtual_size;
 
599
                } else if (!memcmp(buffer, RSRC_SECTION, 8)){
 
600
                        PDEBUG("DECODER:                        RSRC section\n");
 
601
                        rsrc_rva=current_section->virtual_address;
 
602
                        rsrc_size=current_section->virtual_size;
 
603
                } else if (!memcmp(buffer, BSS_SECTION, 8)){
 
604
                        PDEBUG("DECODER:                        BSS section\n");
 
605
                        if (!(current_section->real_address)){  
 
606
                                // The section <.cormeta> can have an empty <.bss> section, if it's happens, i ignore it
 
607
                                num_sections--;
 
608
                                continue;
 
609
                        }
 
610
                }
 
611
 
 
612
                // Check some condition
 
613
                if (current_section->real_size > 0){
 
614
                        if (current_section->real_address < (*min_address)) (*min_address)=current_section->real_address;
 
615
                        if ((current_section->real_address + current_section->real_size) > max_address) max_address=(current_section->real_address + current_section->real_size);
 
616
                }
 
617
                num_sections--;
 
618
        }
 
619
        PDEBUG("DECODER:                End sections\n");
 
620
        PDEBUG("DECODER:                Max address             =       0x%X    %d\n", max_address, max_address);
 
621
        PDEBUG("DECODER:                Min address             =       0x%X    %d\n", *min_address, *min_address);
 
622
        PDEBUG("DECODER:                Checking\n");
 
623
 
 
624
        /* If the maximum address is less than the minimum, then there
 
625
           are no sections in the file, and it cannot possibly be IL */
 
626
        if(max_address <= (*min_address)){
 
627
                print_err("DECODER:             ERROR= This binary is not IL because the maximum address is less than the minimum. ", 0);
 
628
                return -1;
 
629
        }
 
630
        PDEBUG("DECODER:                        Maximum and minimum address are OK\n");
 
631
        
 
632
        /* If we don't have a runtime header yet, then bail out.
 
633
           This can happen if we are processing an object file that
 
634
           does not have a ".text$il" section within it */
 
635
        if(!base){
 
636
                print_err("DECODER:             ERROR= This IL bitecode hasn't the <.text$il> section. ", 0);
 
637
                return -1;
 
638
        }
 
639
        PDEBUG("DECODER:                        <.text$il> section OK\n");
 
640
        assert(binary_info->sections!=NULL);
 
641
        
 
642
        return 0;
 
643
}
 
644
 
 
645
static inline JITINT32 load_metadata (t_binary_information *binary_info){
 
646
        JITUINT32 metadata_real_address;
 
647
        JITINT8 buffer[DIM_BUF];
 
648
 
 
649
        /* Assertions           */
 
650
        assert(binary_info!=NULL);
 
651
        
 
652
        PDEBUG("DECODER:        Read metadata\n");
 
653
        metadata_real_address=convert_virtualaddress_to_realaddress(binary_info->sections, binary_info->cli_information.metadata_RVA);
 
654
        PDEBUG("DECODER:        Computed the metadata address = 0x%X    %d\n", metadata_real_address, metadata_real_address);
 
655
        PDEBUG("DECODER:        Seek to the %d offset\n", metadata_real_address);
 
656
        if(seek_within_file(&(binary_info->binary), buffer, binary_info->binary.offset, metadata_real_address)!=0){
 
657
                print_err("DECODER: ERROR= During seeking the file. ", 0);
 
658
                return -1;
 
659
        }
 
660
        PDEBUG("DECODER:                Call the Metadata manager\n");
 
661
        metadata_init(&(binary_info->metadata));
 
662
        if (read_metadata(&(binary_info->metadata), &(binary_info->binary), binary_info->cli_information.metadata_RVA, binary_info->sections)!=0){
 
663
                print_err("ECMASOFT DECODER: load_metadata: ERROR= Error reading metadata. ", 0);
 
664
                abort();
 
665
        }
 
666
        assert(binary_info->sections != NULL);
 
667
        return 0;
 
668
}
 
669
 
 
670
static inline JITINT32 load_assembly_references (t_binary_information *binary_info){
 
671
        //TODO da implementare
 
672
        return 0;
 
673
}
 
674
 
 
675
char * ecmasoft_getVersion(void){
 
676
        return VERSION;
 
677
}
 
678
 
 
679
char * ecmasoft_getAuthor(void){
 
680
        return "Simone Campanoni";
 
681
}
 
682
 
 
683
char * ecmasoft_getName(void){
 
684
        return "EcmaSoft";
 
685
}
 
686
 
 
687
static inline void ecmasoft_compilationTime (char *buffer, JITINT32 bufferLength){
 
688
        
 
689
        /* Assertions                           */
 
690
        assert(buffer != NULL);
 
691
                        
 
692
        snprintf(buffer, sizeof(char) * bufferLength, "%s %s", __DATE__, __TIME__);
 
693
}
 
694
 
 
695
static inline void ecmasoft_compilationFlags (char *buffer, JITINT32 bufferLength){
 
696
        
 
697
        /* Assertions                           */
 
698
        assert(buffer != NULL);
 
699
 
 
700
        snprintf(buffer, sizeof(char)*bufferLength, " ");
 
701
        #ifdef DEBUG
 
702
        strncat(buffer, "DEBUG ", sizeof(char)*bufferLength);
 
703
        #endif
 
704
        #ifdef PRINTDEBUG
 
705
        strncat(buffer, "PRINTDEBUG ", sizeof(char)*bufferLength);
 
706
        #endif
 
707
        #ifdef PROFILE
 
708
        strncat(buffer, "PROFILE ", sizeof(char)*bufferLength);
 
709
        #endif
 
710
}

Loggerhead 1.17 is a web-based interface for Bazaar branches