update to ida 7.6, add builds
This commit is contained in:
348
idasdk76/ldr/dump/dump.cpp
Normal file
348
idasdk76/ldr/dump/dump.cpp
Normal file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-2001 by Ilfak Guilfanov (ig@datarescue.com)
|
||||
* http://www.datarescue.com
|
||||
* ALL RIGHTS RESERVED.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../idaldr.h"
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static int make_words(char *line, char **words, int maxwords)
|
||||
{
|
||||
while ( qisspace(*line) )
|
||||
line++;
|
||||
int i;
|
||||
for ( i=0; *line && i < maxwords; i++ )
|
||||
{
|
||||
words[i] = line;
|
||||
while ( !qisspace(*line) && *line != '\0' )
|
||||
line++;
|
||||
if ( *line != '\0' )
|
||||
*line++ = '\0';
|
||||
while ( qisspace(*line) )
|
||||
line++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
inline uint32 hex(char *&word)
|
||||
{
|
||||
return strtoul(word, &word, 16);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
inline uint32 oct(char *&word)
|
||||
{
|
||||
return strtoul(word, &word, 8);
|
||||
}
|
||||
|
||||
#define FAILED \
|
||||
do \
|
||||
{ \
|
||||
deb(IDA_DEBUG_LDR, \
|
||||
"failed at %d (input file line %d)\n", \
|
||||
__LINE__, \
|
||||
nl); \
|
||||
return 0; \
|
||||
} while ( false )
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static int idaapi accept_file(
|
||||
qstring *fileformatname,
|
||||
qstring *,
|
||||
linput_t *li,
|
||||
const char *)
|
||||
{
|
||||
char line[MAXSTR];
|
||||
char *words[MAXSTR];
|
||||
|
||||
// We try to interpret the input file as a text
|
||||
// file with a dump format, i.e. all lines should look like
|
||||
|
||||
// 00000020: 59 69 74 54-55 B6 3E F7-D6 B9 C9 B9-45 E6 A4 52
|
||||
// 0020: 59 69 74 54 55 B6 3E F7 D6 B9 C9 B9 45 E6 A4 52
|
||||
// 1000: 12 23 34 56 78
|
||||
// 0100: 31 C7 1D AF 32 04 1E 32 05 1E 3C 32 07 1E 21 D9
|
||||
// 12 23 34 56 78
|
||||
|
||||
// and similar lines
|
||||
// We allow non-ascii characters at the end of the line
|
||||
// We skip empty lines
|
||||
|
||||
ssize_t p0len = -1; // length of the first word's hex part
|
||||
char w0sep[10]; // separator after the first word
|
||||
w0sep[0] = '\0';
|
||||
int nl = 0;
|
||||
int nontrivial_line_count = 0;
|
||||
bool no_more_lines = false;
|
||||
bool has_star = false;
|
||||
uint32 adr, oldadr=0;
|
||||
while ( qlgets(line, sizeof(line), li) )
|
||||
{
|
||||
nl++;
|
||||
strrpl(line, '-', ' ');
|
||||
int nw = make_words(line, words, qnumber(words));
|
||||
if ( line[0] == ';' || line[0] == '#' || nw == 0 )
|
||||
{
|
||||
if ( has_star )
|
||||
FAILED;
|
||||
continue;
|
||||
}
|
||||
if ( no_more_lines )
|
||||
FAILED;
|
||||
// od -x format may contain '*' lines which mean repetition
|
||||
if ( strcmp(words[0], "*") == 0 && nw == 1 )
|
||||
{
|
||||
if ( nontrivial_line_count == 0 )
|
||||
FAILED;
|
||||
if ( has_star )
|
||||
FAILED;
|
||||
has_star = true;
|
||||
continue;
|
||||
}
|
||||
has_star = false;
|
||||
nontrivial_line_count++;
|
||||
// the first word must be a number (more than one digit)
|
||||
char *ptr = words[0];
|
||||
adr = hex(ptr);
|
||||
ssize_t p0 = ptr - words[0];
|
||||
if ( p0 <= 1 || p0 > 16 )
|
||||
FAILED;
|
||||
if ( nontrivial_line_count > 1 && p0 < p0len )
|
||||
FAILED;
|
||||
p0len = p0;
|
||||
// take the separator from the first line
|
||||
if ( nontrivial_line_count == 1 )
|
||||
{
|
||||
qstrncpy(w0sep, ptr, sizeof(w0sep));
|
||||
while ( *ptr )
|
||||
if ( strchr(":>-.", *ptr++) == NULL )
|
||||
FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( strcmp(w0sep, ptr) != 0 )
|
||||
FAILED;
|
||||
}
|
||||
bool haspref = p0len >= 4 || w0sep[0] != '\0';
|
||||
if ( haspref )
|
||||
{
|
||||
// if the line contains only the address, then don't accept lines anymore
|
||||
if ( nw == 1 )
|
||||
{
|
||||
if ( nontrivial_line_count == 1 )
|
||||
FAILED;
|
||||
no_more_lines = true;
|
||||
if ( adr <= oldadr )
|
||||
FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the remaining words should be numbers with at least 1 position
|
||||
// (at least the second word should be so)
|
||||
ptr = words[1];
|
||||
hex(ptr);
|
||||
if ( ptr == words[1] )
|
||||
FAILED;
|
||||
}
|
||||
}
|
||||
oldadr = adr;
|
||||
}
|
||||
if ( nontrivial_line_count == 0 || has_star )
|
||||
FAILED;
|
||||
|
||||
*fileformatname = "Dump file";
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static uchar bytes[MAXSTR/2];
|
||||
static bool iscode;
|
||||
static sel_t sel;
|
||||
static ea_t sea;
|
||||
static ea_t eea;
|
||||
static ushort neflag;
|
||||
|
||||
static void copy(const ea_t ea, const ea_t top)
|
||||
{
|
||||
if ( sea == BADADDR )
|
||||
{
|
||||
if ( neflag & NEF_SEGS )
|
||||
{
|
||||
const char *sname = iscode ? "CODE" : "DATA";
|
||||
sel = setup_selector(0);
|
||||
add_segm(sel, ea, top, sname, sname);
|
||||
}
|
||||
sea = ea;
|
||||
eea = top;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( eea < top )
|
||||
{ // if the gap > 256KB, use sparse storage
|
||||
int flags = top - eea > 256 * 1024 ? SEGMOD_SPARSE : 0;
|
||||
eea = top;
|
||||
set_segm_end(sea, eea, flags);
|
||||
}
|
||||
}
|
||||
mem2base(bytes, ea, top, -1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void idaapi load_file(linput_t *li, ushort _neflag, const char * /*fileformatname*/)
|
||||
{
|
||||
char line[MAXSTR];
|
||||
char *words[MAXSTR];
|
||||
|
||||
neflag = _neflag;
|
||||
iscode = (neflag & NEF_CODE) != 0;
|
||||
sel = BADSEL;
|
||||
sea = BADADDR;
|
||||
ea_t ea = 0;
|
||||
ea_t top= 0;
|
||||
bool octpref = false;
|
||||
bool octnum = false;
|
||||
size_t fill = 0;
|
||||
|
||||
// Since we made all the checks in accept_file,
|
||||
// here we don't repeat them
|
||||
|
||||
size_t max_p0len = 0;
|
||||
char w0sep[10]; // separator after the first word
|
||||
w0sep[0] = '\0';
|
||||
int nontrivial_line_count = 0;
|
||||
while ( qlgets(line, sizeof(line), li) )
|
||||
{
|
||||
strrpl(line, '-', ' ');
|
||||
if ( line[0] == ';' || line[0] == '#' )
|
||||
continue;
|
||||
int n = make_words(line, words, qnumber(words));
|
||||
if ( n == 0 )
|
||||
continue;
|
||||
nontrivial_line_count++;
|
||||
ssize_t bi;
|
||||
// od -x format may contain '*' lines which mean repetition
|
||||
if ( strcmp(words[0], "*") == 0 && n == 1 )
|
||||
{
|
||||
fill = size_t(top - ea);
|
||||
octpref = true; // od -x have octal prefixes
|
||||
continue;
|
||||
}
|
||||
// the first word must be a number (more than one digit)
|
||||
char *ptr = words[0];
|
||||
uint32 w0 = octpref ? oct(ptr) : hex(ptr);
|
||||
// length of the first word's hex part
|
||||
size_t p0len = ptr - words[0];
|
||||
if ( p0len > max_p0len )
|
||||
max_p0len = p0len;
|
||||
|
||||
// take the separator from the first line
|
||||
if ( nontrivial_line_count == 1 )
|
||||
qstrncpy(w0sep, ptr, sizeof(w0sep));
|
||||
|
||||
// process '*' and fill the gap
|
||||
if ( fill > 0 )
|
||||
{
|
||||
while ( top < w0 )
|
||||
{
|
||||
ea = top;
|
||||
top = ea + fill;
|
||||
copy(ea, top);
|
||||
}
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
if ( w0sep[0] != '\0' || p0len >= 4 )
|
||||
{
|
||||
if ( nontrivial_line_count > 1 && !octpref && top != w0 )
|
||||
{
|
||||
// strange, the sequence is not contiguous
|
||||
// check if the prefixes are octal (od -x)
|
||||
ptr = words[0];
|
||||
if ( oct(ptr) == top )
|
||||
{
|
||||
octpref = true;
|
||||
ptr = words[0];
|
||||
w0 = oct(ptr);
|
||||
}
|
||||
}
|
||||
ea = w0;
|
||||
idx = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ea = top;
|
||||
}
|
||||
for ( bi=0; idx < n; idx++ ) //lint !e443
|
||||
{
|
||||
ptr = words[idx];
|
||||
if ( nontrivial_line_count == 1 && !octnum && strlen(ptr) == 6 )
|
||||
{
|
||||
oct(ptr);
|
||||
if ( ptr-words[idx] == 6 )
|
||||
octnum = true;
|
||||
ptr = words[idx];
|
||||
// msg("ptr=%s octnum=%d\n", ptr, octnum);
|
||||
}
|
||||
uint32 b = octnum ? oct(ptr) : hex(ptr);
|
||||
ssize_t nc = ptr - words[idx];
|
||||
if ( nc < 2 )
|
||||
{
|
||||
// we tolerate one-letter separators between numbers
|
||||
if ( words[idx][1] == '\0' && strchr("\xA6|-:", words[idx][0]) != NULL )
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
nc /= octnum ? 3 : 2; // number of bytes
|
||||
*(uint32 *)&bytes[bi] = b;
|
||||
bi += nc;
|
||||
}
|
||||
top = ea + bi;
|
||||
copy(ea, top);
|
||||
}
|
||||
|
||||
if ( neflag & NEF_SEGS )
|
||||
{
|
||||
size_t bitness = eea >= 0x10000 || max_p0len > 4 ? 1 : 0; // 32/16
|
||||
#ifdef __EA64__
|
||||
if ( eea >= ea_t(0x100000000ull) || max_p0len > 8 )
|
||||
bitness = 2; // 64
|
||||
#endif
|
||||
if ( bitness != 0 )
|
||||
{
|
||||
set_segm_addressing(getseg(sea), bitness);
|
||||
inf_set_lflags(inf_get_lflags() | LFLG_PC_FLAT);
|
||||
}
|
||||
set_default_dataseg(sel);
|
||||
}
|
||||
if ( (neflag & NEF_RELOAD) == 0 )
|
||||
create_filename_cmt();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
loader_t LDSC =
|
||||
{
|
||||
IDP_INTERFACE_VERSION,
|
||||
LDRF_REQ_PROC // requires the target processor to the set
|
||||
| LDRF_RELOAD, // supports reloading the input file
|
||||
//
|
||||
// check input file format. if recognized, then return 1
|
||||
// and fill 'fileformatname'.
|
||||
// otherwise return 0
|
||||
//
|
||||
accept_file,
|
||||
//
|
||||
// load file into the database.
|
||||
//
|
||||
load_file,
|
||||
//
|
||||
// create output file from the database.
|
||||
// this function may be absent.
|
||||
//
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
Reference in New Issue
Block a user