update to ida 7.6, add builds

This commit is contained in:
2021-10-31 21:20:46 +02:00
parent e0e0f2be99
commit b1809fe2d9
1408 changed files with 279193 additions and 302468 deletions

149
idasdk76/ldr/ar/aixar.hpp Normal file
View File

@@ -0,0 +1,149 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* bos420 src/bos/usr/include/ar.h */
/* */
/* Licensed Materials - Property of IBM */
/* */
/* (C) COPYRIGHT International Business Machines Corp. 1989,1995 */
/* All Rights Reserved */
/* */
/* US Government Users Restricted Rights - Use, duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/* */
/* IBM_PROLOG_END_TAG */
/* @(#)25 1.8 src/bos/usr/include/ar.h, cmdar, bos420, 9613T 6/16/90 00:07:48 */
/* ar.h 5.1 - 86/12/09 - 06:03:39 */
#ifndef _H_AR
#define _H_AR
#pragma pack(push, 1)
/*
* COMPONENT_NAME: CMDAR
*
* FUNCTIONS: none
*
* ORIGINS: 27, 3
*
* (C) COPYRIGHT International Business Machines Corp. 1989
* All Rights Reserved
* Licensed Materials - Property of IBM
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
/* AIX INDEXED ARCHIVE FORMAT
*
* ARCHIVE File Organization:
* _____________________________________________
* |__________FIXED HEADER "fl_hdr"______________|
* +--- | |
* | |__________ARCHIVE_FILE_MEMBER_1______________|
* +--> | |
* | Archive Member Header "ar_hdr" |
* +--- |.............................................| <--+
* | | Member Contents | |
* | |_____________________________________________| |
* | |________ARCHIVE_FILE_MEMBER_2________________| |
* +--> | | ---+
* | Archive Member Header "ar_hdr" |
* +--- |.............................................| <--+
* | | Member Contents | |
* | |_____________________________________________| |
* | | . . . | |
* . | . . . | .
* . | . . . | .
* . |_____________________________________________| .
* | |________ARCHIVE_FILE_MEMBER_n-1______________| |
* +--> | | ---+
* | Archive Member Header "ar_hdr" |
* +--- |.............................................| <--+
* | | Member Contents | |
* | | (Member Table, always present) | |
* | |_____________________________________________| |
* | |_____________________________________________| |
* | |________ARCHIVE_FILE_MEMBER_n________________| |
* | | | |
* +--> | Archive Member Header "ar_hdr" | ---+
* |.............................................|
* | Member Contents |
* | (Global Symbol Table if present) |
* |_____________________________________________|
*
*/
#define AIAMAG "<aiaff>\n"
#define AIAMAGBIG "<bigaf>\n"
#define SAIAMAG 8
#define AIAFMAG "`\n"
struct fl_hdr /* archive fixed length header */
{
char fl_magic[SAIAMAG]; /* Archive magic string */
char fl_memoff[20]; /*Offset to member table */
char fl_gstoff[20]; /*Offset to global symbol table */
char fl_gst64off[20]; /*Offset global symbol table for 64-bit objects */
char fl_fstmoff[20]; /*Offset to first archive member */
char fl_lstmoff[20]; /*Offset to last archive member */
char fl_freeoff[20]; /*Offset to first mem on free list */
};
struct aix_ar_hdr /* archive file member header - printable ascii */
{
char ar_size[20]; /* File member size - decimal */
char ar_nxtmem[20]; /* Next member offset-decimal */
char ar_prvmem[20]; /* Previous member offset-dec */
char ar_date[12]; /* File member date-decimal */
char ar_uid[12]; /* File member userid-decimal */
char ar_gid[12]; /* File member group id-decimal */
char ar_mode[12]; /* File member mode-octal */
char ar_namlen[4]; /* File member name length-dec */
#if 0
union
{
char ar_name[2]; /* variable length member name */
char ar_fmag[2]; /* AIAFMAG - string to end header */
} _ar_name; /* and variable length name */
#endif
};
struct fl_hdr_small /* archive fixed length header (prior to Version 4.3) */
{
char fl_magic[SAIAMAG]; /* Archive file magic string */
char fl_memoff[12]; /* Offset to member table */
char fl_gstoff[12]; /* Offset to global symbol table */
char fl_fstmoff[12]; /* Offset to first archive member */
char fl_lstmoff[12]; /* Offset to last archive member */
char fl_freeoff[12]; /* Offset to first mem on free list */
};
struct aix_ar_hdr_small /* archive file member header - printable ascii */
{
char ar_size[12]; /* file member size - decimal */
char ar_nxtmem[12]; /* pointer to next member - decimal */
char ar_prvmem[12]; /* pointer to previous member - decimal */
char ar_date[12]; /* file member date - decimal */
char ar_uid[12]; /* file member user id - decimal */
char ar_gid[12]; /* file member group id - decimal */
char ar_mode[12]; /* file member mode - octal */
char ar_namlen[4]; /* file member name length - decimal */
#if 0
union
{
char ar_name[2]; /* variable length member name */
char ar_fmag[2]; /* AIAFMAG - string to end header */
} _ar_name; /* and variable length name */
#endif
};
/*
* Note: 'ar_namlen' contains the length of the member name which
* may be up to 255 chars. The character string containing
* the name begins at '_ar_name.ar_name'. The terminating
* string AIAFMAG, is only cosmetic. File member contents begin
* at the first even byte boundary past 'header position +
* sizeof(struct ar_hdr) + ar_namlen', and continue for
* 'ar_size' bytes.
*/
#pragma pack(pop)
#endif /* _H_AR */

113
idasdk76/ldr/ar/ar.hpp Normal file
View File

@@ -0,0 +1,113 @@
/* So far this is correct for BSDish archives. Don't forget that
files must begin on an even byte boundary. */
#ifndef __AR_H__
#define __AR_H__
#pragma pack(push, 1)
/* Note that the usual '\n' in magic strings may translate to different
characters, as allowed by ANSI. '\012' has a fixed value, and remains
compatible with existing BSDish archives. */
#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
#define ARMAGB "!<bout>\012" /* For b.out archives */
#define ARMAGE "!<elf_>\012" /* For ELF archives */
#define SARMAG 8
#define ARFMAG "`\012"
/* The ar_date field of the armap (__.SYMDEF) member of an archive
must be greater than the modified date of the entire file, or
BSD-derived linkers complain. We originally write the ar_date with
this offset from the real file's mod-time. After finishing the
file, we rewrite ar_date if it's not still greater than the mod date. */
#define ARMAP_TIME_OFFSET 60
struct ar_hdr
{
char ar_name[16]; /* name of this member */
char ar_date[12]; /* file mtime */
char ar_uid[6]; /* owner uid; printed as decimal */
char ar_gid[6]; /* owner gid; printed as decimal */
char ar_mode[8]; /* file mode, printed as octal */
char ar_size[10]; /* file size, printed as decimal */
char ar_fmag[2]; /* should contain ARFMAG */
};
#define AR_EFMT1 "#1/" /* extended format #1: BSD/Apple archives */
// ig. get all module names from ar
int process_ar(
char *libfile, /* return 0 - ok */
int (*_callback)(
void *ud,
int32 offset,
int method,
uint32 csize,
uint32 ucsize,
uint32 attributes,
const char *filename),
void *ud);
// The first linker member has the following format. This information appears after the
// header:
//
// Offset Size Field Description
// 0 4 Number of Symbols Unsigned long containing the number of symbols indexed.
// This number is stored in big-endian format. Each object-file member
// typically defines one or more external symbols.
// 4 4*n Offsets Array of file offsets to archive member headers, in which n is
// equal to Number of Symbols. Each number in the array is an unsigned long
// stored in big-endian format. For each symbol named in the String Table,
// the corresponding element in the Offsets array gives the location of the
// archive member that contains the symbol.
// * * String Table Series of null-terminated strings that name all the symbols
// in the directory. Each string begins immediately after the null character
// in the previous string. The number of strings must be equal to the value
// of the Number of Symbols fields.
//
// -----------------------------
// The second linker member has the name '\' as does the first linker member. Although
// both the linker members provide a directory of symbols and archive members that contain
// them, the second linker member is used in preference to the first by all current
// linkers. The second linker member includes symbol names in lexical order, which enables
// faster searching by name.
//
// The first second member has the following format. This information appears after the
// header:
//
// Offset Size Field Description
// 0 4 Number of Members Unsigned long containing the number of archive members.
// 4 4*m Offsets Array of file offsets to archive member headers, arranged in
// ascending order. Each offset is an unsigned long. The number m is equal
// to the value of the Number of Members field.
// * 4 Number of Symbols Unsigned long containing the number of symbols indexed.
// Each object-file member typically defines one or more external symbols.
// * 2*n Indices Array of 1-based indices (unsigned short) which map symbol names
// to archive member offsets. The number n is equal to Number of Symbols.
// For each symbol named in the String Table, the corresponding element in
// the Indices array gives an index into the Offsets array. The Offsets
// array, in turn, gives the location of the archive member that contains
// the symbol.
// * * String Table Series of null-terminated strings that name all the symbols
// in the directory. Each string begins immediately after the null byte in
// the previous string. The number of strings must be equal to the value of
// the Number of Symbols fields. This table lists all the symbol names in
// ascending lexical order.
//
// //-----------------------------
// The name of the longnames member is '\\'. The longnames member is a series of
// strings of archive member names. A name appears here only when there is insufficient
// room in the Name field (16 bytes). The longnames member can be empty, though its
// header must appear.
//
// The strings are null-terminated. Each string begins immediately after the null byte
// in the previous string.
//
bool is_ar_file(linput_t *li, qoff64_t offset, bool include_aix);
#pragma pack(pop)
#endif /* __AR_H__ */

238
idasdk76/ldr/ar/arcmn.cpp Normal file
View File

@@ -0,0 +1,238 @@
#include <diskio.hpp>
#define MAGICLEN ((SARMAG > SAIAMAG) ? SARMAG : SAIAMAG)
//------------------------------------------------------------------------
bool is_ar_file(linput_t *li, qoff64_t offset, bool include_aix)
{
char magic[MAGICLEN];
qlseek(li, offset);
if ( qlread(li, magic, sizeof(magic)) != sizeof(magic) )
return false;
return memcmp(magic, ARMAG, SARMAG) == 0
|| memcmp(magic, ARMAGB, SARMAG) == 0
|| memcmp(magic, ARMAGE, SARMAG) == 0
|| include_aix
&& (memcmp(magic,AIAMAG,SAIAMAG) == 0
|| memcmp(magic,AIAMAGBIG,SAIAMAG) == 0);
}
//------------------------------------------------------------------------
static char *get_msft_module_name(
const char *ahname,
const char *ahend,
char *name,
size_t size)
{
if ( size == 0 )
return NULL;
char *ptr = name;
for ( size_t i=0; ahname < ahend; i++,ptr++ )
{
char chr = *ahname++;
if ( chr == '\n' || i == size-1 )
chr = '\0';
*ptr = chr;
if ( chr == '\0' )
break;
}
while ( ptr > name && qisspace(ptr[-1]) )
*--ptr = '\0';
if ( ptr > name && ptr[-1] == '/' )
ptr[-1] = '\0';
return name;
}
//------------------------------------------------------------------------
static const char *get_ar_modname(
const char *lnames,
const char *end,
const char *name,
char *buf,
size_t bufsize)
{
if ( lnames != NULL && *name == '/' )
{
name++;
size_t off = size_t(atol(name));
while ( qisdigit(*name) )
name++;
if ( *name == '\0' )
{
if ( lnames+off < lnames )
return qstrncpy(buf, "?", bufsize);
return get_msft_module_name(lnames+off, end, buf, bufsize);
}
}
return qstrncpy(buf, name, bufsize);
}
//------------------------------------------------------------------------
// return codes:
// 0: ok
// 1: no input file
// 2: read error
// 3: bad archive
// 4: not enough memory
// 5: maxpos reached
struct ar_visitor_t
{
virtual ssize_t idaapi visit_ar_module(
qoff64_t offset,
ar_hdr *ah,
uint64 size,
char *filename) = 0;
};
// Enumerate modules in AR archive.
// \param maxpos Max position in file. Typically is used when
// archive is embedded within other file.
ssize_t enum_ar_contents(linput_t *li, ar_visitor_t &av, int32 maxpos = -1)
{
ssize_t code = 0;
char *names = NULL;
size_t names_size = 0;
while ( true )
{
ar_hdr ah;
qoff64_t filepos = qltell(li);
if ( filepos & 1 )
qlseek(li, filepos+1);
if ( maxpos > -1 && filepos >= maxpos )
{
code = 5;
break;
}
ssize_t bytes = qlread(li, &ah, sizeof(ah));
if ( bytes == 0 )
break; // end of archive, no error
if ( bytes != sizeof(ah) )
{
code = 2; // read error
break;
}
if ( memcmp(ah.ar_fmag, ARFMAG, sizeof(ah.ar_fmag)) != 0 )
{
code = 3; // bad archive
break;
}
char name[sizeof(ah.ar_name)+1];
get_msft_module_name(ah.ar_name, ah.ar_name+sizeof(ah.ar_name), name, sizeof(name));
uint64 size = qatoll(ah.ar_size);
filepos = qltell(li);
if ( names == NULL && name[0] == '/' && name[1] == '\0' )
{
if ( size != 0 )
{
names = (char *)qalloc(size);
if ( names == NULL )
{
code = 4; // not enough memory
break;
}
names_size = size;
if ( qlread(li, names, size) != size )
{
code = 2; // read error
break;
}
}
continue;
}
if ( memcmp(name, AR_EFMT1, 3) == 0 )
{
// BSD/Apple archive: the length of long name follows
// #1/nnn
size_t extralen = size_t(atol(name+3));
char *modname = (char *)qalloc(extralen+1);
if ( modname == NULL )
{
code = 4; // not enough memory
break;
}
if ( qlread(li, modname, extralen) != extralen )
{
code = 2; // read error
break;
}
modname[extralen]='\0';
// skip special files
if ( !strneq(modname, "__.SYMDEF", sizeof("__.SYMDEF")-1) )
{
code = av.visit_ar_module(qoff64_t(filepos+extralen), &ah, size-extralen, modname);
if ( code != 0 )
break;
}
qfree(modname);
}
else if ( name[0] != '\0' )
{
char modname[MAXSTR];
get_ar_modname(names, names+names_size, name, modname, sizeof(modname));
code = av.visit_ar_module(filepos, &ah, size, modname);
if ( code != 0 )
break;
}
qlseek(li, qoff64_t(filepos+size));
}
qfree(names);
return code;
}
//--------------------------------------------------------------------------
// convert small archive header to big one
bool upgrade_aix_fl_hdr(fl_hdr *fh, const fl_hdr_small *fh_small)
{
if ( memcmp(fh_small->fl_magic, AIAMAG, SAIAMAG) != 0 )
return false; // not small archive
qstrncpy(fh->fl_memoff, fh_small->fl_memoff, sizeof(fh->fl_memoff));
qstrncpy(fh->fl_gstoff, fh_small->fl_gstoff, sizeof(fh->fl_gstoff));
fh->fl_gst64off[0] = '\0';
qstrncpy(fh->fl_fstmoff, fh_small->fl_fstmoff, sizeof(fh->fl_fstmoff));
qstrncpy(fh->fl_lstmoff, fh_small->fl_lstmoff, sizeof(fh->fl_lstmoff));
qstrncpy(fh->fl_freeoff, fh_small->fl_freeoff, sizeof(fh->fl_freeoff));
return true;
}
//--------------------------------------------------------------------------
bool read_aix_fl_hdr(fl_hdr *fh, linput_t *li)
{
size_t nread = qlread(li, fh, sizeof(*fh));
if ( nread == sizeof(*fh) && memcmp(fh->fl_magic, AIAMAGBIG, SAIAMAG) == 0 )
return true;
if ( nread < sizeof(fl_hdr_small) )
return false;
fl_hdr_small fh_small;
memcpy(&fh_small, fh, sizeof(fh_small)); //-V512 call of the 'memcpy' function will lead to underflow of the buffer
return upgrade_aix_fl_hdr(fh, &fh_small);
}
//--------------------------------------------------------------------------
// convert small member header to big one
void upgrade_aix_ar_hdr(aix_ar_hdr *ah, const aix_ar_hdr_small *ah_small)
{
qstrncpy(ah->ar_size, ah_small->ar_size, sizeof(ah->ar_size));
qstrncpy(ah->ar_nxtmem, ah_small->ar_nxtmem, sizeof(ah->ar_nxtmem));
qstrncpy(ah->ar_prvmem, ah_small->ar_prvmem, sizeof(ah->ar_prvmem));
qstrncpy(ah->ar_date, ah_small->ar_date, sizeof(ah->ar_date));
qstrncpy(ah->ar_uid, ah_small->ar_uid, sizeof(ah->ar_uid));
qstrncpy(ah->ar_gid, ah_small->ar_gid, sizeof(ah->ar_gid));
qstrncpy(ah->ar_mode, ah_small->ar_mode, sizeof(ah->ar_mode));
qstrncpy(ah->ar_namlen, ah_small->ar_namlen, sizeof(ah->ar_namlen));
}
//--------------------------------------------------------------------------
bool read_aix_ar_hdr(aix_ar_hdr *ah, const fl_hdr *fh, linput_t *li)
{
if ( memcmp(fh->fl_magic, AIAMAGBIG, SAIAMAG) == 0 )
return qlread(li, ah, sizeof(*ah)) == sizeof(*ah);
aix_ar_hdr_small ah_small;
if ( qlread(li, &ah_small, sizeof(ah_small)) != sizeof(ah_small) )
return false;
upgrade_aix_ar_hdr(ah, &ah_small);
return true;
}